#include <catch2/catch.hpp>
#include <tuple>

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

enum class Op {
	DERIVATION,
	INTEGRAL
};


TEST_CASE ( "RegExp Derivation/Integral test", "[integration]" ) {
	static const std::string mdfa = "regexp::convert::ToAutomatonGlushkov - | automaton::determinize::Determinize - | automaton::simplify::Trim - | automaton::simplify::Minimize - | automaton::simplify::Normalize -";

	auto definition = GENERATE ( as < std::tuple < Op, std::string, std::string, std::string > > ( ),
			std::make_tuple ( Op::DERIVATION, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.13.xml$" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.13.d0.xml$" ),   "0" ),
			std::make_tuple ( Op::DERIVATION, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.13.xml$" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.13.d00.xml$" ),  "0 0" ),
			std::make_tuple ( Op::DERIVATION, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.14.xml$" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.14.d1.xml$" ),   "1" ),
			std::make_tuple ( Op::DERIVATION, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.14.xml$" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.14.d10.xml$" ),  "1 0" ),
			std::make_tuple ( Op::DERIVATION, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.15.xml$" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.15.d100.xml$" ), "1 0 0" ),
			std::make_tuple ( Op::INTEGRAL, TestFiles::GetOne ( "/regexp/unbounded.oppa.4.16.xml" ), TestFiles::GetOne ( "/regexp/unbounded.oppa.4.16.i1.xml" ), "1" ),
			std::make_tuple ( Op::INTEGRAL, TestFiles::GetOne ( "/regexp/Melichar2-94.xml" ),        TestFiles::GetOne ( "/regexp/Melichar2-94.i0.xml" ), "0" ),
			std::make_tuple ( Op::INTEGRAL, TestFiles::GetOne ( "/regexp/Melichar2-94.xml" ),        TestFiles::GetOne ( "/regexp/Melichar2-94.i1.xml" ), "1" ) );

	std::vector < std::string > qs = {
		"execute < " + std::get < 1 > ( definition ) + " > $regexp",
		"execute < " + std::get < 2 > ( definition ) + " > $result",
		"execute \"\\\"" + std::get < 3 > ( definition ) + "\\\"\"" + " | Move - | string::Parse @string::String - > $string",
		"quit compare::AutomatonCompare <( $result | " + mdfa + " ) <( regexp::transform::RegExp" + ( std::get < 0 > ( definition ) == Op::DERIVATION ? "Derivation" : "Integral" ) + " $regexp $string | " + mdfa + " )"
	};

	TimeoutAqlTest ( 1s, qs );
}
