/*
 * BWTBinarySearchTest.cpp
 *
 *  Created on: 19. 02. 2021
 *      Author: Martin Prokopic
 */

#include <catch2/catch.hpp>

#include <string/String.h>
#include <stringology/transform/BWTNaive.h>
#include <stringology/exact/BWTBoyerMoore.h>

using stringology::transform::BWTNaive;
using stringology::indexing::BWTAuxiliaryDataConstruct;
using stringology::exact::BWTBoyerMoore;
using string::LinearStringTerminatingSymbolBWT;

TEST_CASE ( "BWT Boyer Moore", "[unit][stringology][bwt]" ) {

    SECTION ( "simple hardcoded examples" ) {
        auto testcase = GENERATE (
                std::make_tuple("banana", "na", ext::set< unsigned > { 2, 4 }),
                std::make_tuple("banana", "ana", ext::set< unsigned > { 1, 3 }),
                std::make_tuple("banana", "ba", ext::set< unsigned > { 0 }),
                std::make_tuple("banana", "z", ext::set< unsigned > ()),
                std::make_tuple("banana", "asdf", ext::set< unsigned >()),
                std::make_tuple("banana", "bananaba", ext::set< unsigned >()),
                std::make_tuple("", "asdf", ext::set< unsigned >()) );

        auto originalSubject = string::stringFrom(std::get<0>(testcase));
        auto pattern = string::stringFrom(std::get<1>(testcase));

        auto transformedSubject = stringology::transform::BWTNaive::construct(originalSubject);

        auto auxData = BWTAuxiliaryDataConstruct::construct(transformedSubject);
        INFO ( auxData );

        auto matches = BWTBoyerMoore::match(transformedSubject, pattern);
        REQUIRE ( matches == std::get<2>(testcase) );
    }

    SECTION ( "throws exception if pattern is empty" ) {
        auto subject = LinearStringTerminatingSymbolBWT < char >('$', string::stringFrom("subject$"));
        auto pattern = string::stringFrom("");

        REQUIRE_THROWS_AS(BWTBoyerMoore::match(subject, pattern), exception::CommonException);
    }
}