/*
 * Copyright 2009-2010 Yuichiro Moriguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.morilib.awk;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import net.morilib.awk.code.AwkExecutable;
import net.morilib.awk.misc.RecordInputStream;

/**
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/03/09
 */
public class ExtendAwkProgramTest extends AwkTestCase {

	public void testProgram0171() {
		AwkExecutable e = pre("" +
				"BEGIN { IGNORECASE = 1 }" +
				"{ print \"a\" == \"A\", " +
				"        \"a\" != \"A\", " +
				"        \"a\" <  \"B\", " +
				"        \"a\" <= \"B\", " +
				"        \"a\" >  \"B\", " +
				"        \"a\" >= \"B\" }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "1");
		eot("1 0 1 1 0 0");
	}

	public void testProgram0172() {
		AwkExecutable e = pre("" +
				"BEGIN { IGNORECASE = 1 }" +
				"{ print \"a\" ~ /A/, \"a\" !~ /A/, match(\"a\", /A/) }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "1");
		eot("1 0 1");
	}

	public void testProgram0173() {
		AwkExecutable e = pre("" +
				"BEGIN { IGNORECASE = 1 }" +
				"{ print sub(/a/, \"b\")," +
				"        gsub(/a/, \"b\")," +
				"        gensub(/a/, \"b\", 2) }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "AA");
		eot("bA bb Ab");
	}

	public void testProgram0174() {
		AwkExecutable e = pre("" +
				"{ print \"a\" == \"A\", " +
				"        \"a\" != \"A\", " +
				"        \"a\" <  \"B\", " +
				"        \"a\" <= \"B\", " +
				"        \"a\" >  \"B\", " +
				"        \"a\" >= \"B\" }");

		e.execute(ns0, fs0, "1");
		eot("0 1 0 0 1 1");
	}

	public void testProgram0175() {
		AwkExecutable e = pre("" +
				"{ print \"a\" ~ /A/, \"a\" !~ /A/, match(\"a\", /A/) }");

		e.execute(ns0, fs0, "1");
		eot("0 1 0");
	}

	public void testProgram0176() {
		AwkExecutable e = pre("" +
				"{ print sub(/a/, \"b\")," +
				"        gsub(/a/, \"b\")," +
				"        gensub(/a/, \"b\", 2) }");

		e.execute(ns0, fs0, "AA");
		eot("AA AA AA");
	}

	public void testProgram0101() {
		AwkExecutable e = pre("" +
				"function$ aaa() { print a++; }" +
				"{ aaa(); print a; }");

		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "aaa bbb");
		eot("0");
		eot("");
		eot("1");
		eot("");
		eot("2");
		eot("");
	}

	public void testProgram0111() {
		AwkExecutable e = pre("" +
				"BEGIN { aaa = function() { print 1; }; }\n" +
				"{ aaa(); }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "aaa bbb");
		eot("1");
		eot("1");
		eot("1");
	}

	public void testProgram0112() {
		AwkExecutable e = pre("" +
				"BEGIN { aaa = function(a) { print a; }; }\n" +
				"{ aaa($1); }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "ccc bbb");
		e.execute(ns0, fs0, "ddd bbb");
		eot("aaa");
		eot("ccc");
		eot("ddd");
	}

	public void testProgram0113() {
		AwkExecutable e = pre("" +
				"BEGIN { aaa = function(a, b) { print a, b; }; }\n" +
				"{ aaa($1, $2); }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "ccc bbb");
		e.execute(ns0, fs0, "ddd bbb");
		eot("aaa bbb");
		eot("ccc bbb");
		eot("ddd bbb");
	}

	public void testProgram0114() {
		AwkExecutable e = pre("" +
				"function$ aaa(a) { print a; }\n" +
				"function$ bbb(a, b) { a(b); }\n" +
				"{ bbb(@aaa, $1); }");

		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "ccc bbb");
		e.execute(ns0, fs0, "ddd bbb");
		eot("aaa");
		eot("ccc");
		eot("ddd");
	}

	public void testProgram0115() {
		AwkExecutable e = pre("" +
				"function$ aaa() { a = 0; function() { print a++; }; }\n" +
				"BEGIN { bbb = aaa(); }\n" +
				"{ bbb(); }\n" +
				"END { print a; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaa bbb");
		e.execute(ns0, fs0, "ccc bbb");
		e.execute(ns0, fs0, "ddd bbb");
		e.executeEnd(ns0, fs0);
		eot("0");
		eot("1");
		eot("2");
		eot("");
	}

	public void testProgram0121() {
		AwkExecutable e = pre("" +
				"function$ ns.aaa(a, b) { print a, b; }" +
				"{ ns.aaa($1, $2); }");

		e.execute(ns0, fs0, "aaa bbb");
		eot("aaa bbb");
	}

	public void testProgram0122() {
		AwkExecutable e = pre("" +
				"function$ ns.aaa(a, b) { bbb(a, b); }\n" +
				"function$ ns.bbb(a, b) { print a, b; }\n" +
				"{ ns.aaa($1, $2); }");

		e.execute(ns0, fs0, "aaa bbb");
		eot("aaa bbb");
	}

	public void testProgram0131() {
		AwkExecutable e = pre("" +
				"function ns.new(a, b) { x = a; y = b }\n" +
				"function ns.aaa() { print x, y }\n" +
				"{\n" +
				"  c = ns.new(1, 2)\n" +
				"  d = ns.new(3, 4)\n" +
				"  print c.x, c.y, c.a\n" +
				"  print d.x, d.y, d.a\n" +
				"  c.aaa()\n" +
				"  d.aaa()\n" +
				"}");

		e.execute(ns0, fs0, "aaa bbb");
		eot("1 2 ");
		eot("3 4 ");
		eot("1 2");
		eot("3 4");
	}

	public void testProgram0141() {
		eqi("a[2][2] = 3;", 3);
		eqi("a[2][2];", 3);
		eqi("a[3][2][1] = 4;", 4);
		eqi("a[3][2][1];", 4);
	}

	public void testProgram0151() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed\"\n" +
				"	FS = \"7 6 5\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "chihayamakotoazusa012345");
		e.execute(ns0, fs0, "chihayamakotoazusa");
		e.execute(ns0, fs0, "chihayamakotomiki");
		e.execute(ns0, fs0, "chihayaami");
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("azusachihayamakoto012345");
		eot("azusachihayamakoto");
		eot("mikichihayamakoto");
		eot("chihayaami");
		eot("miki  yayoi azusa ");
	}

	public void testProgram0152() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed trim\"\n" +
				"	FS = \"7 6 5\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("mikiyayoiazusa");
	}

	public void testProgram0153() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed trim\"\n" +
				"	FS = \"\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("yayoi azusa miki");
	}

	public void testProgram0154() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed trim\"\n" +
				"	FS = \"7 a 6 5\"\n" +
				"}\n" +
				"{ print $4 $1 $2 $3 $5; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("mikiyayoiazusa");
	}

	public void testProgram0155() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed trim\"\n" +
				"	FS = \"7 -1 6 5\"\n" +
				"}\n" +
				"{ print $4 $1 $2 $3 $5; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("mikiyayoiazusa");
	}

	public void testProgram0156() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	FIELDWIDTHS = \"7 6 5\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "chihayamakotoazusa012345");
		e.execute(ns0, fs0, "chihayamakotoazusa");
		e.execute(ns0, fs0, "chihayamakotomiki");
		e.execute(ns0, fs0, "chihayaami");
		e.execute(ns0, fs0, " yayoi azusa miki ");
		eot("azusachihayamakoto012345");
		eot("azusachihayamakoto");
		eot("mikichihayamakoto");
		eot("chihayaami");
		eot("miki  yayoi azusa ");
	}

	public void testProgram0157() {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	FIELDWIDTHS = \"7 6 5\"\n" +
				"   FS = FS\n" +
				"}\n" +
				"{ print $1, $2; }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaaa  bbbb");
		eot("aaaa bbbb");
	}

	public void testProgram0161() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed\"\n" +
				"	RMODE   = \"binary\"\n" +
				"	FS = \"7 6 5\"\n" +
				"	RS = \"18\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4 }");
		RecordInputStream rd = new RecordInputStream(
				new ByteArrayInputStream(
						"chihayamakotoazusachihayamakotomiki chihayaami".getBytes()),
				ns0);

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, rd.readRecord());
		e.execute(ns0, fs0, rd.readRecord());
		e.execute(ns0, fs0, rd.readRecord());
		eot("azusachihayamakoto");
		eot("miki chihayamakoto");
		eot("chihayaami");
		rd.close();
	}

	public void testProgram0162() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed\"\n" +
				"	RMODE   = \"fixed\"\n" +
				"	FS = \"7 6 5\"\n" +
				"	RS = \"18\"\n" +
				"}\n" +
				"{ print $3 $1 $2 $4 }");
		RecordInputStream rd = new RecordInputStream(
				new ByteArrayInputStream(
						"chihayamakotoazusachihayamakotomiki chihayaami".getBytes()),
				ns0);

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, rd.readRecord());
		e.execute(ns0, fs0, rd.readRecord());
		e.execute(ns0, fs0, rd.readRecord());
		eot("azusachihayamakoto");
		eot("miki chihayamakoto");
		eot("chihayaami");
		rd.close();
	}

	public void testProgram0163() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"fixed\"\n" +
				"	RMODE   = \"binary\"\n" +
				"	FS = \"3 2\"\n" +
				"	RS = \"5\"\n" +
				"}\n" +
				"{ print b.uat($1, 1), b.uat($1, 2), b.uat($1, 3), b.uat($2, 1), b.uat($2, 2) }");
		RecordInputStream rd = new RecordInputStream(
				new ByteArrayInputStream(
						"\u00ff\u00fe\u00fd\u00fc\u00fb\u00fa\u00f9\u00f8\u00f7\u00f6".getBytes("ISO-8859-1")),
				ns0);

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, rd.readRecord());
		e.execute(ns0, fs0, rd.readRecord());
		eot("255 254 253 252 251");
		eot("250 249 248 247 246");
		rd.close();
	}

	public void testProgram0164() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"property\"\n" +
				"	FS = \" \"\n" +
				"}\n" +
				"{ print $0, $1, $2 }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaaa   bbbb   ccc");
		e.execute(ns0, fs0, "aaaabbbb");
		e.execute(ns0, fs0, "aaaabbbb    ");
		eot("aaaa   bbbb   ccc aaaa bbbb   ccc");
		eot("aaaabbbb aaaabbbb ");
		eot("aaaabbbb     aaaabbbb ");
	}

	public void testProgram0165() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"property\"\n" +
				"	FS = \"=\"\n" +
				"}\n" +
				"{ print $0, $1, $2 }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaaa=bbbb=ccc");
		e.execute(ns0, fs0, "aaaa==bbbb");
		e.execute(ns0, fs0, "aaaabbbb");
		e.execute(ns0, fs0, "aaaabbbb=");
		eot("aaaa=bbbb=ccc aaaa bbbb=ccc");
		eot("aaaa==bbbb aaaa =bbbb");
		eot("aaaabbbb aaaabbbb ");
		eot("aaaabbbb= aaaabbbb ");
	}

	public void testProgram0166() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"property\"\n" +
				"	FS = \"\"\n" +
				"}\n" +
				"{ print $0, $1, $2 }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaaa bbbb ccc");
		eot("aaaa bbbb ccc aaaa bbbb ccc ");
	}

	public void testProgram0167() throws IOException {
		AwkExecutable e = pre("" +
				"BEGIN {" +
				"	SEPMODE = \"property\"\n" +
				"	FS = \"=+\"\n" +
				"}\n" +
				"{ print $0, $1, $2 }");

		e.executeBegin(ns0, fs0);
		e.execute(ns0, fs0, "aaaa==bbbb==ccc");
		e.execute(ns0, fs0, "aaaabbbb==");
		e.execute(ns0, fs0, "aaaabbbb");
		eot("aaaa==bbbb==ccc aaaa bbbb==ccc");
		eot("aaaabbbb== aaaabbbb ");
		eot("aaaabbbb aaaabbbb ");
	}

}
