//
// Created by hruskraj on 28. 4. 2020
//

#include <catch2/catch.hpp>

#include <alib/set>
#include <string/LinearString.h>
#include <stringology/cover/ApproximateEnhancedCoversComputation.h>

TEST_CASE ( "Approximate Enhanced Covers", "[unit][stringology][cover]" ) {
	SECTION ( "Basic test" ) {
		unsigned int k;
		string::LinearString < char > pattern;
		ext::set < string::LinearString < char > > refSet;

		SECTION ( "One simple enhanced cover" ) {
			k = 1;
			pattern = string::LinearString < char > ( "abacaccababa" );
			refSet = { string::LinearString < char > ( "aba" ) };
		}

		SECTION ( "Multiple enhanced covers" ) {
			k = 2;
			pattern = string::LinearString < char > ( "ababaccababa" );
			refSet = { string::LinearString < char > ( "aba" ), string::LinearString < char > ( "ababa" ) };
		}

		CHECK ( stringology::cover::ApproximateEnhancedCoversComputation::compute ( pattern, k ) == refSet );
	}

	SECTION ( "Empty string" ) {
		string::LinearString < char > pattern ( "" );
		unsigned int k;

		SECTION ( "k = 0" ) {
			k = 0;
		}
		SECTION ( "k = 1" ) {
			k = 1;
		}
		SECTION ( "k = 15" ) {
			k = 15;
		}
		SECTION ( "k = -1" ) {
			k = -1;
		}

		CHECK ( stringology::cover::ApproximateEnhancedCoversComputation::compute ( pattern, k ).empty ( ) );
	}

	SECTION ( "k = 0 (enhanced covers)" ) {
		unsigned int k = 0;

		string::LinearString < char > pattern;
		ext::set < string::LinearString < char > > refSet;

		SECTION ( "pattern x" ) {
			pattern = string::LinearString < char > { "x" };
			refSet = {};
		}

		SECTION ( "pattern ab" ) {
			pattern = string::LinearString < char > { "ab" };
			refSet = {};
		}

		SECTION ( "pattern aa" ) {
			pattern = string::LinearString < char > { "aa" };
			refSet = { string::LinearString < char > { "a" } };
		}

		SECTION ( "pattern aba" ) {
			pattern = string::LinearString < char > { "aba" };
			refSet = { string::LinearString < char > { "a" } };
		}

		SECTION ( "pattern aaa" ) {
			pattern = string::LinearString < char > { "aaa" };
			refSet = { string::LinearString < char > { "a" }, string::LinearString < char > { "aa" } };
		}

		CHECK ( stringology::cover::ApproximateEnhancedCoversComputation::compute ( pattern, k ) == refSet );
	}

	SECTION ( "Different k" ) {
		string::LinearString < char > pattern;
		ext::set < string::LinearString < char > > refSet;
		unsigned int k = 0;

		SECTION ( "pattern 1" ) {
			pattern = string::LinearString < char > { "adesgvsade" };

			SECTION ( "k = 3" ) {
				k = 3;
				refSet = {};
			}

			SECTION ( "k = 2" ) {
				k = 2;
				refSet = { string::LinearString < char > { "ade" } };
			}
		}

		SECTION ( "pattern 2" ) {
			pattern = string::LinearString < char > { "abcd" };

			SECTION ( "k = 1" ) {
				k = 1;
				refSet = {};
			}
		}

		CHECK ( stringology::cover::ApproximateEnhancedCoversComputation::compute ( pattern, k ) == refSet );
	}
}
