/*
 * SimpleFMIndexTest.cpp
 *
 *  Created on: 27. 02. 2021
 *      Author: Martin Prokopic
 */

#include "catch2/catch.hpp"

#include <indexes/xml/stringology/SimpleFMIndex.h>
#include <factory/XmlDataFactory.hpp>
#include <string/String.h>

using indexes::stringology::SimpleFMIndex;
using string::LinearStringTerminatingSymbolBWT;
using object::Object;
using factory::XmlDataFactory;

TEST_CASE ( "Simple FM Index", "[unit][indexes][stringology]" ) {

    auto charStr = LinearStringTerminatingSymbolBWT < char > ( '$', string::stringFrom ( "annb$aa" ));
    auto str = core::normalize < LinearStringTerminatingSymbolBWT < char >>::eval ( std::move ( charStr ));

    SimpleFMIndex < Object > normalized ( str, 4, 2, ext::vector < ext::map < Object, unsigned>>{
            { },
            {
                    { Object ( 'a' ), 1u },
                    { Object ( 'b' ), 1u },
                    { Object ( 'n' ), 2u },
            }
    }, ext::vector < ext::map < Object, unsigned>>{
            { },
            {
                    { Object ( 'a' ), 1u },
                    { Object ( 'n' ), 1u }
            },
            { },
            {
                    { Object ( '$' ), 1u },
                    { Object ( 'a' ), 1u }
            }
    }, ext::map < Object, unsigned >{
            { Object ( '$' ), 0 },
            { Object ( 'a' ), 1 },
            { Object ( 'b' ), 4 },
            { Object ( 'n' ), 5 },
    }, ext::map < Object, unsigned >{
            { Object ( '$' ), 1 },
            { Object ( 'a' ), 3 },
            { Object ( 'b' ), 1 },
            { Object ( 'n' ), 2 },
    }, Object ( 'n' ), ext::vector < unsigned >{ 5, 3 } );

    SECTION ( "xmlApi parse and compose" ) {
        std::string xml = XmlDataFactory::toString ( normalized );
        INFO( xml );
        REQUIRE ( static_cast<SimpleFMIndex < Object >>(XmlDataFactory::fromString ( xml )) == normalized );
    }

    SECTION ( "normalization" ) {
        auto charStr2 = LinearStringTerminatingSymbolBWT < char > ( '$', string::stringFrom ( "annb$aa" ));

        SimpleFMIndex < char > original ( charStr2, 4, 2, ext::vector < ext::map < char, unsigned>>{
                { },
                {
                        { 'a', 1u }, { 'b', 1u }, { 'n', 2u },
                }
        }, ext::vector < ext::map < char, unsigned>>{
                { },
                {
                        { 'a', 1u }, { 'n', 1u }
                },
                { },
                {
                        { '$', 1u }, { 'a', 1u }
                }
        }, ext::map < char, unsigned >{
                { '$', 0 },
                { 'a', 1 },
                { 'b', 4 },
                { 'n', 5 },
        }, ext::map < char, unsigned >{
                { '$', 1 },
                { 'a', 3 },
                { 'b', 1 },
                { 'n', 2 },
        }, 'n', ext::vector < unsigned >{ 5, 3 } );

        auto normalized2 = core::normalize < SimpleFMIndex < char > >::eval ( std::move ( original ));
        REQUIRE( normalized == normalized2 );
    }

}