//
// Created by shushiri on 18.2.19.
//

#include <catch2/catch.hpp>

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

TEST_CASE ( "Approximate Covers", "[unit][stringology][cover]" ) {
	SECTION ( "Test 1" ) {
		string::LinearString < char > pattern( "acacca" );
		unsigned int k = 1;

		ext::set < ext::pair < string::LinearString < char >, unsigned > > refSet;
		string::LinearString < char > a1 ("aa");
		string::LinearString < char > a2 ("aca");
		string::LinearString < char > a3 ("cc");
		string::LinearString < char > a4 ("cca");
		string::LinearString < char > a5 ("accc");
		string::LinearString < char > a6 ("acaa");
		refSet.insert( ext::make_pair( a1, 1 ) );
		refSet.insert( ext::make_pair( a2, 1 ) );
		refSet.insert( ext::make_pair( a3, 1 ) );
		refSet.insert( ext::make_pair( a4, 1 ) );
		refSet.insert( ext::make_pair( a5, 1 ) );
		refSet.insert( ext::make_pair( a6, 1 ) );

		ext::set < ext::pair < string::LinearString < char >, unsigned > > result = stringology::cover::ApproximateCoversComputation::compute( pattern, k, 0 );

		CHECK ( result == refSet );
	}

	SECTION ( "Test 2" ) {
		string::LinearString < char > pattern( "aca" );
		unsigned int k = 1;

		ext::set < ext::pair < string::LinearString < char >, unsigned > > refSet;
		string::LinearString < char > b1 ("aa");
		string::LinearString < char > b2 ("cc");
		refSet.insert( ext::make_pair( b1, 1 ) );
		refSet.insert( ext::make_pair( b2, 1 ) );

		ext::set < ext::pair < string::LinearString < char >, unsigned > >result = stringology::cover::ApproximateCoversComputation::compute( pattern, k, 0 );

		CHECK( result == refSet );
	}

	SECTION ( "Test 3" ) {
		string::LinearString < char > pattern( "abab" );
		unsigned int k = 1;

		ext::set < ext::pair < string::LinearString < char >, unsigned > > refSet;
		string::LinearString < char > c1 ("aa");
		string::LinearString < char > c2 ("ab");
		string::LinearString < char > c3 ("bb");

		refSet.insert( ext::make_pair( c1, 1 ) );
		refSet.insert( ext::make_pair( c2, 0 ) );
		refSet.insert( ext::make_pair( c3, 1 ) );

		ext::set < ext::pair < string::LinearString < char >, unsigned > > result = stringology::cover::ApproximateCoversComputation::compute( pattern, k, 0 );

		CHECK( result == refSet );
	}

	SECTION ( "Test 4" ) {
		string::LinearString < char > pattern( "" );
		unsigned int k = 1;

		ext::set < ext::pair < string::LinearString < char >, unsigned > > result = stringology::cover::ApproximateCoversComputation::compute( pattern, k, 0 );

		CHECK( result.size() == 0 );
	}

	SECTION ( "Test 5" ) {
		string::LinearString < char > pattern ( "abab" );
		unsigned int k = 2;

		ext::set < ext::pair < string::LinearString < char >, unsigned > > refSet;

		string::LinearString < char > d1 ("aaa");
		string::LinearString < char > d2 ("aab");
		string::LinearString < char > d3 ("abb");
		string::LinearString < char > d4 ("baa");
		string::LinearString < char > d5 ("bba");
		string::LinearString < char > d6 ("bbb");
		string::LinearString < char > d7 ("ab");
		string::LinearString < char > d8 ("aa");
		string::LinearString < char > d9 ("bb");

		refSet.insert( ext::make_pair( d1, 2 ) );
		refSet.insert( ext::make_pair( d2, 2 ) );
		refSet.insert( ext::make_pair( d3, 2 ) );
		refSet.insert( ext::make_pair( d4, 2 ) );
		refSet.insert( ext::make_pair( d5, 2 ) );
		refSet.insert( ext::make_pair( d6, 2 ) );
		refSet.insert( ext::make_pair( d7, 0 ) );
		refSet.insert( ext::make_pair( d8, 1 ) );
		refSet.insert( ext::make_pair( d9, 1 ) );

		ext::set < ext::pair < string::LinearString < char >, unsigned > > result = stringology::cover::ApproximateCoversComputation::compute( pattern, k, 0 );

		CHECK( result == refSet );
	}
}

