//
// Created by dolanver on 2/16/20.
//

#include <catch2/catch.hpp>
#include <stringology/seed/RestrictedApproximateSeedComputation.h>


TEST_CASE ( "Restricted approximate seed computation", "[unit][stringology][seed]" ) {
	string::LinearString < char > pattern;
	size_t k;
	ext::set < ext::pair < string::LinearString < char >, unsigned > > expectedSeeds;

    SECTION ( "Compute restricted approximate seeds for empty string with Hamming distance 2" ) {
        pattern = string::LinearString < char > ( "" );
        k = 2;
		expectedSeeds = { };
    }

    SECTION ( "Compute restricted approximate seeds for 'abcabc' with Hamming distance = 0" ) {
        pattern = string::LinearString < char > ( "abcabc" );
        k = 0;
		expectedSeeds = {
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'a', 'b', 'c' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'b', 'c', 'a' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'c', 'a', 'b' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'a', 'b', 'c', 'a' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'b', 'c', 'a', 'b' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'c', 'a', 'b', 'c' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'a', 'b', 'c', 'a', 'b' } ), 0 },
			{ string::LinearString < char > ( { 'a', 'b', 'c' }, { 'b', 'c', 'a', 'b', 'c' } ), 0 },
		};
    }

    SECTION ( "Compute restricted approximate seeds for 'abxabcab' with Hamming distance = 1" ) {
        pattern = string::LinearString < char > ( "abxabcab" );
        k = 1;
		expectedSeeds = {
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'c'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'c', 'a'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'c', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'x'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'x', 'a'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'x', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'x', 'a', 'b', 'c'} ), 0 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'a', 'b', 'x', 'a', 'b', 'c', 'a'} ), 0 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'c', 'a'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'c', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'x', 'a'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'x', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'x', 'a', 'b', 'c'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'x', 'a', 'b', 'c', 'a'} ), 0 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'b', 'x', 'a', 'b', 'c', 'a', 'b'} ), 0 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'c', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'x', 'a', 'b'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'x', 'a', 'b', 'c'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'x', 'a', 'b', 'c', 'a'} ), 1 },
			{ string::LinearString < char >( { 'a', 'b', 'c', 'x' }, {'x', 'a', 'b', 'c', 'a', 'b'} ), 0 },
		};
	}

	CHECK ( stringology::seed::RestrictedApproximateSeedComputation::compute ( pattern, k ) == expectedSeeds );
}
