#include <catch2/catch.hpp>
#include <alib/vector>
#include <ext/sstream>

#include "testing/TimeoutAqlTest.hpp"
#include "testing/TestFiles.hpp"

const unsigned LEAF_NODES   = 10;
const unsigned HEIGHT = 6;
const double   ALPHABET_SIZE  = 2;
const size_t   ITERATIONS = 100;

std::string qGenRE ( ) {
	return ext::concat ( "execute regexp::generate::RandomRegExpFactory (size_t)", rand ( ) % LEAF_NODES + 1, " (size_t)", rand ( ) % HEIGHT + 1, "<(alphabet::generate::GenerateAlphabet (size_t)", ALPHABET_SIZE, " false false)" );
}

TEST_CASE ( "RE optimize test", "[integration]" ) {
	static const std::string qMinimize1 ( "automaton::simplify::efficient::EpsilonRemoverOutgoing - | automaton::determinize::Determinize - | "
			"automaton::simplify::Trim - | automaton::simplify::Minimize - | automaton::simplify::Normalize -" );

	static const std::string qMinimize2 ( "automaton::simplify::efficient::EpsilonRemoverIncoming - | automaton::determinize::Determinize - | "
			"automaton::simplify::Trim - | automaton::simplify::Minimize - | automaton::simplify::Normalize -" );

	SECTION ( "Random tests" ) {
		for ( size_t i = 0; i < ITERATIONS; i++ ) {
			ext::vector < std::string > qs = {
				ext::concat ( qGenRE ( ), " > $gen" ),
				"execute string::Compose $gen > /tmp/file",
				ext::concat ( "quit compare::AutomatonCompare <( $gen | regexp::convert::ToAutomaton - | ", qMinimize1, " ) <( $gen | regexp::simplify::RegExpOptimize - | regexp::convert::ToAutomaton - | ", qMinimize2, ")" )
			};
			TimeoutAqlTest ( 10s, qs );
		}
	}
}