#include <catch2/catch.hpp>

#include <stringology/matching/SequenceMatchingAutomaton.h>
#include <automaton/FSM/NFA.h>
#include <string/LinearString.h>
#include <automaton/simplify/UnreachableStatesRemover.h>

TEST_CASE ( "Sequence Matching Automaton", "[unit][algo][stringology][matching]" ) {
	SECTION ( "Test construction" ) {
		ext::set<char> alphabet{'a', 'b', 'c', 'd'};
		string::LinearString <char> input_string(alphabet, ext::vector<char>{'a', 'b', 'c'});
		auto resulting_automata = stringology::matching::SequenceMatchingAutomaton::construct(input_string);

		automaton::NFA <char, unsigned int> test(0);
		test.setInputAlphabet(ext::set<char>{'a', 'b', 'c', 'd'});
		test.setStates(ext::set<unsigned int> {0, 1, 2, 3});
		test.addFinalState(3);

		test.addTransition(0, 'a', 0); // initial loop over whole alphabet
		test.addTransition(0, 'b', 0);
		test.addTransition(0, 'c', 0);
		test.addTransition(0, 'd', 0);

		test.addTransition(0, 'a', 1); // part of a sequence

		test.addTransition(1, 'a', 1);
		test.addTransition(1, 'c', 1);
		test.addTransition(1, 'd', 1);

		test.addTransition(1, 'b', 2); // part of a sequence

		test.addTransition(2, 'a', 2);
		test.addTransition(2, 'b', 2);
		test.addTransition(2, 'd', 2);

		test.addTransition(2, 'c', 3); // part of a sequence

		CHECK(test == automaton::simplify::UnreachableStatesRemover::remove(resulting_automata));
	}
}
