#include <catch2/catch.hpp>

#include "string/naive/ExactEqual.h"
#include "string/naive/ExactCompare.h"
#include "string/simplify/NormalizeRotation.h"
#include "string/LinearString.h"
#include "string/CyclicString.h"

TEST_CASE ( "String Compare", "[unit][algo][string][compare]" ) {
	SECTION ( "Cyclic String Equality" ) {
		string::CyclicString < > str1("alfa");
		string::CyclicString < > str2("aalf");
		str2.extendAlphabet(str1.getAlphabet());
		str1.extendAlphabet(str2.getAlphabet());

		CHECK(string::naive::ExactEqual::equals(str1, str2));
	}

	SECTION ( "Cyclic String integer pos" ) {
		string::CyclicString < > str1("alfa");
		string::CyclicString < > str2("aalf");
		str2.extendAlphabet(str1.getAlphabet());
		str1.extendAlphabet(str2.getAlphabet());

		CHECK(string::naive::ExactCompare::compare(str1, str2) == 0);

		string::CyclicString < > str3("ccbcccb");
		string::CyclicString < > str4("cbcccbc");
		str2.extendAlphabet(str1.getAlphabet());
		str1.extendAlphabet(str2.getAlphabet());

		CHECK(string::naive::ExactCompare::compare(str3, str4) == 0);
	}

	SECTION ( "Compare Cyclic" ) {
		string::CyclicString < > cyclic1({DefaultSymbolType(0), DefaultSymbolType(1), DefaultSymbolType(2)});
		string::CyclicString < > cyclic2({DefaultSymbolType(1), DefaultSymbolType(2), DefaultSymbolType(0)});
		string::CyclicString < > cyclic3({DefaultSymbolType(2), DefaultSymbolType(0), DefaultSymbolType(1)});

		string::CyclicString < > cyclic4({DefaultSymbolType(2), DefaultSymbolType(1), DefaultSymbolType(0)});

		string::CyclicString < > cyclic1n = string::simplify::NormalizeRotation::normalize(cyclic1);
		string::CyclicString < > cyclic2n = string::simplify::NormalizeRotation::normalize(cyclic2);
		string::CyclicString < > cyclic3n = string::simplify::NormalizeRotation::normalize(cyclic3);
		string::CyclicString < > cyclic4n = string::simplify::NormalizeRotation::normalize(cyclic4);

		CHECK(cyclic1  == cyclic1n);
		CHECK(cyclic1n == cyclic2n);
		CHECK(cyclic1n == cyclic3n);
		CHECK(cyclic2n == cyclic3n);

		CHECK(cyclic4n != cyclic1n);
		CHECK(cyclic4n != cyclic2n);
		CHECK(cyclic4n != cyclic3n);

		string::CyclicString < > cyclic5({DefaultSymbolType(62), DefaultSymbolType(62), DefaultSymbolType(100), DefaultSymbolType(62)});
		string::CyclicString < > cyclic5n = string::simplify::NormalizeRotation::normalize(cyclic5);
		string::CyclicString < > cyclic5r({DefaultSymbolType(62), DefaultSymbolType(62), DefaultSymbolType(62), DefaultSymbolType(100)});
		CHECK(cyclic5n == cyclic5r);
	}
}
