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

#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 ( ) {
	std::ostringstream oss;
	oss << "execute regexp::generate::RandomRegExpFactory ";
	oss << "(size_t)" << rand ( ) % LEAF_NODES + 1 << " ";
	oss << "(size_t)" << rand ( ) % HEIGHT + 1 << " ";
	oss << "(size_t)" << ALPHABET_SIZE << " ";
	oss << "(bool)false ";
	return oss.str ( );
}

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 = {
				qGenRE ( ) + " > $gen",
				"execute string::Compose $gen > /tmp/file",
				"quit compare::AutomatonCompare <( $gen | regexp::convert::ToAutomaton - | " + qMinimize1 + " )" + " <( $gen | regexp::simplify::RegExpOptimize - | regexp::convert::ToAutomaton - | " + qMinimize2 + ")"
			};
			TimeoutAqlTest ( 10s, qs );
		}
	}
}
