#include <catch2/catch.hpp>
#include <alib/vector>
#include <extensions/container/string.hpp>

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

const size_t SIZE = 100;
const size_t HEIGHT = 15;
const size_t ALPHABET_SIZE = 10;
const size_t RANDOM_ITERATIONS = 15;

TEST_CASE ( "TreeRepeats", "[integration]" ) {
	auto pipeline = GENERATE ( as < std::string > ( ),
		"arbology::properties::ExactSubtreeRepeatsFromSubtreeAutomaton (PrefixRankedTree)$tree | tree::simplify::NormalizeTreeLabels (RankedTree) -",
		"tree::properties::ExactSubtreeRepeatsNaive (PostfixRankedTree)$tree | tree::simplify::NormalizeTreeLabels (RankedTree) -",
		"tree::properties::ExactSubtreeRepeatsNaive (PostfixRankedTree)$tree | tree::simplify::NormalizeTreeLabels (RankedTree) -" );


	SECTION ( "Test Files" ) {
		for ( const std::string & file : TestFiles::Get ( "/tree/repeats.*.xml" ) ) {
			ext::vector < std::string > qs = {
				"execute < " + file + " > $tree",
				"execute tree::properties::ExactSubtreeRepeatsNaive $tree | tree::simplify::NormalizeTreeLabels - > $res1", // naive
				"execute " + pipeline + " > $res2",
				"quit compare::TreeCompare $res1 $res2",
			};

			TimeoutAqlTest ( 2s, qs );
		}
	}

	SECTION ( "Random tests" ) {
		for ( size_t i = 0; i < RANDOM_ITERATIONS; i++ ) {
			ext::vector < std::string > qs = {
				"execute tree::generate::RandomRankedTreeFactory " + ext::to_string ( HEIGHT ) + " " + ext::to_string ( SIZE ) + " " + ext::to_string ( rand ( ) % ALPHABET_SIZE + 1 ) + " (bool)true 5 > $tree",
				"execute tree::properties::ExactSubtreeRepeatsNaive $tree | tree::simplify::NormalizeTreeLabels - > $res1", // naive
				"execute " + pipeline + " > $res2",
				"quit compare::TreeCompare $res1 $res2",
			};

			TimeoutAqlTest ( 2s, qs );
		}
	}
}
