/*
 * Copyright 2013 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 net.morilib.automata.DFA;
import net.morilib.automata.NFA;
import net.morilib.automata.NFAState;
import net.morilib.automata.dfa.ConvertedDFA;
import net.morilib.automata.dfa.DFAs;
import net.morilib.automata.regular.BasicRegex;
import net.morilib.nina.NinaParser;
import junit.framework.TestCase;

public class NinaTest extends TestCase {

	static void drv(String s, boolean pause) {
		DFA<Object, NFAState, Void> d;
		NinaNFA n;
		NFABuilder a;
		NinaParser m;
		BasicRegex b;
		Quadro q;
		Object o;

		q = Quadro.read("A", s, Collections.<String>emptyList());
		a = new NFABuilder();
		m = new NinaParser(q, a, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				new NinaConsoleStub(), new NinaConsoleStub());
		try {
			while((o = m.step()) == null) {
				if(pause) {
//					System.in.read();
					m.printTrace(System.out);
				}
			}
			n = (NinaNFA)((NFABuilder)o).getMachine();
			System.out.print(n);
			d = ConvertedDFA.convertDFA(n);
			b = DFAs.convertToRegex(d);
			System.out.println(b);
			System.out.println("-------------------------------");
		} catch(Exception e) {
			m.printTrace(System.out);
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("unchecked")
	public void test0000() {
		String s =
				"#machine NFABuilder\n" +
				"         \n" +
				" &====== \n" +
				" =aaa  = \n" +
				" ======= \n" +
				"";
		NFA<Object, NFAState, Void> o;

		o = (NFA<Object, NFAState, Void>)Nina.compile("A",
				s, Collections.<String, String>emptyMap(),
				new NinaSubautomata("a"),
				Collections.<String>emptyList(),
				new NinaConsoleStub()).getMachine();
		System.out.println(o.toString());
	}

	public void test0001() {
		String s =
				"#machine NFABuilder\n" +
				"         \n" +
				" &====== \n" +
				" =aaa  = \n" +
				" ======= \n" +
				"";

		drv(s, false);
	}

	public void test0002() {
		String s =
				"#machine NFABuilder\n" +
				"                  \n" +
				" =******   ****   \n" +
				" *aaa  >-A->b *   \n" +
				" ***v***   *v**   \n" +
				"    B       C     \n" +
				"    |       |     \n" +
				" @**v***  @*v*    \n" +
				" *bbb  *  *c *    \n" +
				" *******  ****    \n" +
				"";

		drv(s, true);
	}

	public void test0003() {
		String s =
				"#machine NFABuilder\n" +
				"#type string\n" +
				"                      \n" +
				" &******       ****   \n" +
				" *aaa  >-'aaa'->b *   \n" +
				" ***v***       *v**   \n" +
				"    B           C     \n" +
				"    |           |     \n" +
				" @**v***      @*v*    \n" +
				" *bbb  *      *c *    \n" +
				" *******      ****    \n" +
				"";

		drv(s, false);
	}

	public void test0004() {
		String s =
				"#machine NFABuilder\n" +
				"                      \n" +
				" =======       @***   \n" +
				" =aaa  >---+-a->b *   \n" +
				" ===v===   |   ****   \n" +
				"    B      |          \n" +
				"    |      |          \n" +
				" @**v***   |  @***    \n" +
				" *bbb  *   \\c->c *    \n" +
				" *******      ****    \n" +
				"";

		drv(s, false);
	}

	public void test0005() {
		String s =
				"#machine NFABuilder\n" +
				"    /--c---\\          \n" +
				" &==v===   |   @***   \n" +
				" =aaa  >---+-a->b *   \n" +
				" ===v===       ****   \n" +
				"    B                 \n" +
				"    |                 \n" +
				" @**v***              \n" +
				" *bbb  *              \n" +
				" *******              \n" +
				"";

		drv(s, false);
	}

	public void test0006() {
		String s =
				"#machine NFABuilder\n" +
				" /---------\\   \n" +
				" | =====   |    \n" +
				" | =a  =   |    \n" +
				" | =v===   |    \n" +
				" |  |      |    \n" +
				" |  \\-a----/   \n" +
				" \\\\           \n" +
				" @v*****        \n" +
				" *bbb  *        \n" +
				" *******        \n" +
				"";

		drv(s, false);
	}

	public void test0007() {
		String s =
				"#machine NFABuilder\n" +
				"    /------\\          \n" +
				" &==v===   |   @***   \n" +
				" =aaa  >-a-+--->b *   \n" +
				" ===v===       ****   \n" +
				"    B                 \n" +
				"    |                 \n" +
				" @**v***              \n" +
				" *bbb  *              \n" +
				" *******              \n" +
				"";

		drv(s, false);
	}

	public void test0008() {
		String s =
				"#machine NFABuilder\n" +
				" /---------\\   \n" +
				" | =====   |    \n" +
				" | =a  =   |    \n" +
				" | =v===   |    \n" +
				" |  |      |    \n" +
				" |  \\------/   \n" +
				" \\\\           \n" +
				" @v*****        \n" +
				" *bbb  *        \n" +
				" *******        \n" +
				"";

		drv(s, false);
	}

	public void test0009() {
		String s =
				"#machine NFABuilder\n" +
				" =======      @*****\n" +
				" =aaa  >---a-->aa  *\n" +
				" ==^====      **v***\n" +
				"   \\---b--------/  \n" +
				"";

		drv(s, false);
	}

	public void test0010() {
		String s =
				"#machine NFABuilder\n" +
				" =======                                @*****\n" +
				" =aaa  >-----------------a-------------->aa  *\n" +
				" ==^====                                **v***\n" +
				"   \\--------------------a-----------------/  \n" +
				"";

		drv(s, false);
	}

	public void test0011() {
		String s =
				"#machine NFABuilder\n" +
				" =======              @*****\n" +
				" =aaa  >-a-(1)  (1)--->aa  *\n" +
				" ==^====              **v***\n" +
				"   \\-----(2)   (2)--a---/  \n" +
				"";

		drv(s, false);
	}

	public void test0012() {
		String s =
				"#machine NFABuilder\n" +
				" =======              @*****\n" +
				" =aaa  >-a-(1)  (2)-b-<aa  *\n" +
				" ==^====              **^***\n" +
				"   \\-----(2)   (1)------/  \n" +
				"";

		drv(s, false);
	}

	public void test0013() {
		String s =
				"#machine NFABuilder\n" +
				" =======     *****                      @*****\n" +
				" =aaa  >----->b  >-------a-------------->aa  *\n" +
				" =======     **v**                      **^***\n" +
				"               \\---------b----------------/  \n" +
				"";

		drv(s, false);
	}

	public void test0014() {
		String s =
				"#machine NFABuilder\n" +
				" =======     *****             @*****         \n" +
				" =aaa  >----->b  >-------a----->aa  <------\\  \n" +
				" =======     **v**             ******      |  \n" +
				"               \\---------b-----------------/  \n" +
				"";

		drv(s, false);
	}

	public void test0015() {
		String s =
				"#machine NFABuilder\n" +
				" =======*****             @*****         \n" +
				" =aaa  >>b  >-------a----->aa  <------\\  \n" +
				" =======**v**             ******      |  \n" +
				"          \\---------b-----------------/  \n" +
				"";

		drv(s, false);
	}

}
