/*
 * 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.nina;

import java.util.Collections;

import junit.framework.TestCase;

/**
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/10/13
 */
public class NinaMultibyteMatcherTest extends TestCase {

	static void mat(NinaPattern m, String s) {
		NinaMatcher x;

		x = m.matcher(s);
		assertTrue(x.matches());
	}

	static void nmt(NinaPattern m, String s) {
		NinaMatcher x;

		x = m.matcher(s);
		assertFalse(x.matches());
	}

	static void lok(NinaPattern m, String s, String d) {
		NinaMatcher x;

		x = m.matcher(s);
		assertTrue(x.lookingAt());
		assertEquals(d, x.group());
	}

	static void fnd(NinaPattern m, String s, String d) {
		NinaMatcher x;

		x = m.matcher(s);
		assertTrue(x.find());
		assertEquals(d, x.group());
	}

	public void test0001() {
		String s =
				"#machine NFABuilder\n" +
				" =======             @@@@@@\n" +
				" =aaa  >-----あ------>aa  @\n" +
				" =======             @@@@@@\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "あ");
		nmt(m, "");
		nmt(m, "ああ");

		lok(m, "あaa", "あ");
		assertFalse(m.matcher("aあ").lookingAt());

		fnd(m, "aあa", "あ");
		assertFalse(m.matcher("aaa").find());
	}

	public void test0002() {
		String s =
				"#machine NFABuilder\n" +
				" =======             @@@@@@\n" +
				" =aaa  >----'あ'----->aa  @\n" +
				" =======             @@@@@@\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "あ");
		nmt(m, "");
		nmt(m, "ああ");

		lok(m, "あaa", "あ");
		assertFalse(m.matcher("aあ").lookingAt());

		fnd(m, "aあa", "あ");
		assertFalse(m.matcher("aaa").find());
	}

	public void test0003() {
		String s =
				"#machine NFABuilder\n" +
				" =======               @@@@@@\n" +
				" =aaa  >----'あい'----->aa  @\n" +
				" =======               @@@@@@\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "あい");
		nmt(m, "");
		nmt(m, "あいあ");

		lok(m, "あいaa", "あい");
		assertFalse(m.matcher("aあい").lookingAt());

		fnd(m, "aあいa", "あい");
		assertFalse(m.matcher("aあaa").find());
	}

	public void test0004() {
		String s =
				"#machine NFABuilder\n" +
				" =======               @@@@@@\n" +
				" =aaa  >----[あい]----->aa  @\n" +
				" =======               @@@@@@\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "あ");
		mat(m, "い");
		nmt(m, "");
		nmt(m, "あいあ");

		lok(m, "あいaa", "あ");
		lok(m, "いあaa", "い");
		assertFalse(m.matcher("aあい").lookingAt());

		fnd(m, "aあいa", "あ");
		assertFalse(m.matcher("aうaa").find());
	}

	public void test0005() {
		String s =
				"#machine NFABuilder\n" +
				" =======                @@@@@@\n" +
				" =aaa  >----/あ+い/----->aa  @\n" +
				" =======                @@@@@@\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "あい");
		mat(m, "あああい");
		nmt(m, "");
		nmt(m, "い");
		nmt(m, "あいあ");

		lok(m, "あいaa", "あい");
		lok(m, "ああああいaa", "ああああい");
		assertFalse(m.matcher("aあい").lookingAt());

		fnd(m, "aあいa", "あい");
		fnd(m, "aああああいa", "ああああい");
		assertFalse(m.matcher("aあaa").find());
	}

	public void test0011() {
		String s =
				"#machine NFABuilder\n" +
				" &&&&&&&             ******\n" +
				" &aaa  >-----い------>aa  *\n" +
				" &^&&&&&             ****v*\n" +
				"  |                      | \n" +
				"  に                     ろ\n" +
				"  |                      | \n" +
				" =^=====             ****v*\n" +
				" =aaa  <-----は------<aa  *\n" +
				" =======             ******\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "");
		mat(m, "いろはに");
		mat(m, "いろはにいろはに");
		nmt(m, "いろは");

		lok(m, "いろはにaa", "いろはに");
		lok(m, "いろはにいろはにaa", "いろはにいろはに");
		assertFalse(m.matcher("aいろはに").lookingAt());

		fnd(m, "aいろはにa", "いろはに");
		fnd(m, "aいろはにいろはにa", "いろはにいろはに");
		assertFalse(m.matcher("aいろはaa").find());
	}

	public void test0012() {
		String s =
				"#machine NFABuilder\n" +
				" &&&&&&&             ******\n" +
				" &aaa  >-----[あい]-->aa  *\n" +
				" &^&&&&&             ****v*\n" +
				"  |                      | \n" +
				"  に                     ろ\n" +
				"  |                      | \n" +
				" =^=====             ****v*\n" +
				" =aaa  <-----[はう]--<aa  *\n" +
				" =======             ******\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "");
		mat(m, "いろはに");
		mat(m, "あろうに");
		mat(m, "いろはにあろうに");
		nmt(m, "いろは");

		lok(m, "いろはにaa", "いろはに");
		lok(m, "いろはにあろうにaa", "いろはにあろうに");
		assertFalse(m.matcher("aいろはに").lookingAt());

		fnd(m, "aいろはにa", "いろはに");
		fnd(m, "aいろはにあろうにa", "いろはにあろうに");
		assertFalse(m.matcher("aいろはaa").find());
	}

	public void test0013() {
		String s =
				"#machine NFABuilder\n" +
				" &&&&&&&             ******\n" +
				" &aaa  >-----'いろ'-->aa  *\n" +
				" &^&&&&&             ****v*\n" +
				"  |                      | \n" +
				"  へ                     は\n" +
				"  |                      | \n" +
				" =^=====             ****v*\n" +
				" =aaa  <-----'にほ'--<aa  *\n" +
				" =======             ******\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "");
		mat(m, "いろはにほへ");
		mat(m, "いろはにほへいろはにほへ");
		nmt(m, "いろは");

		lok(m, "いろはにほへaa", "いろはにほへ");
		lok(m, "いろはにほへいろはにほへaa", "いろはにほへいろはにほへ");
		assertFalse(m.matcher("aいろはに").lookingAt());

		fnd(m, "aいろはにほへa", "いろはにほへ");
		fnd(m, "aいろはにほへいろはにほへa", "いろはにほへいろはにほへ");
		assertFalse(m.matcher("aいろはaa").find());
	}

	public void test0014() {
		String s =
				"#machine NFABuilder\n" +
				" &&&&&&&             ******\n" +
				" &aaa  >-----/い+ろ/->aa  *\n" +
				" &^&&&&&             ****v*\n" +
				"  |                      | \n" +
				"  へ                     は\n" +
				"  |                      | \n" +
				" =^=====             ****v*\n" +
				" =aaa  <-----/に+ほ/-<aa  *\n" +
				" =======             ******\n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "");
		mat(m, "いろはにほへ");
		mat(m, "いろはにほへいいいろはににににほへ");
		nmt(m, "いろは");

		lok(m, "いろはにほへaa", "いろはにほへ");
		lok(m, "いろはにほへいいいろはににににほへaa", "いろはにほへいいいろはににににほへ");
		assertFalse(m.matcher("aいろはに").lookingAt());

		fnd(m, "aいろはにほへa", "いろはにほへ");
		fnd(m, "aいろはにほへいいいろはににににほへa", "いろはにほへいいいろはににににほへ");
		assertFalse(m.matcher("aいろはaa").find());
	}

	public void test0051() {
		String s =
				"#machine DFABuilder\n" +
				" =======                              @*****\n" +
				" =aaa  >-----------'ﾆﾅﾁｬｰﾝ'----------->aa  *\n" +
				" ==^====                              **v***\n" +
				"   \\--------------'Ｎｉｎａ￠'----------/  \n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "ﾆﾅﾁｬｰﾝ");
		mat(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝ");
		mat(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝ");
		nmt(m, "");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝＮｉｎａ￠");
	}

	public void test0061() {
		String s =
				"#machine DFABuilder\n" +
				" &********************************\n" +
				" *aaa                            *\n" +
				" *v*****************************^*\n" +
				"  +-[\\p{InXHalfwidthKatakana}]--+  \n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "ﾆﾅﾁｬｰﾝ");
		mat(m, "ﾆﾅﾁｬｰﾝﾆﾅﾁｬｰﾝ");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝＮｉｎａ￠");
	}

	public void test0062() {
		String s =
				"#machine DFABuilder\n" +
				" &********************************\n" +
				" *aaa                            *\n" +
				" *v*****************************^*\n" +
				"  +-[\\p{InXFullwidthLatin}]-----+  \n" +
				"";
		NinaPattern m;

		m = Nina.pattern("A", s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub());
		mat(m, "Ｎｉｎａ￠");
		mat(m, "Ｎｉｎａ￠Ｎｉｎａ￠");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠");
		nmt(m, "ﾆﾅﾁｬｰﾝＮｉｎａ￠ﾆﾅﾁｬｰﾝＮｉｎａ￠");
	}

}
