#include "TestFramework.h"
#include "htio2/Kmer.h"

#include <limits>

using namespace htio2;
using namespace std;

typedef uint16_t KmerType;

void TestFramework::content()
{
    IS(ENCODED_NT4_A, 0);
    IS(ENCODED_NT4_T, 3);
    IS(ENCODED_NT4_G, 1);
    IS(ENCODED_NT4_C, 2);

    IS(encode_nt4('N'), ENCODED_ERROR);
    IS(encode_nt4('A'), ENCODED_NT4_A);
    IS(encode_nt4('T'), ENCODED_NT4_T);
    IS(encode_nt4('G'), ENCODED_NT4_G);
    IS(encode_nt4('C'), ENCODED_NT4_C);
    IS(encode_nt4('Z'), ENCODED_ERROR);
    IS(encode_nt4('B'), ENCODED_ERROR);

    IS(decode_nt4(ENCODED_ERROR), 'N');
    IS(decode_nt4(ENCODED_NT4_A), 'A');
    IS(decode_nt4(ENCODED_NT4_T), 'T');
    IS(decode_nt4(ENCODED_NT4_G), 'G');
    IS(decode_nt4(ENCODED_NT4_C), 'C');

    // encode
    EncodedSeq enc;
    encode_nt4("ATGXCATA", enc);
    IS(enc.size(), 8);
    IS(enc[0], ENCODED_NT4_A);
    IS(enc[1], ENCODED_NT4_T);
    IS(enc[2], ENCODED_NT4_G);
    IS(enc[3], ENCODED_ERROR);
    IS(enc[4], ENCODED_NT4_C);
    IS(enc[5], ENCODED_NT4_A);
    IS(enc[6], ENCODED_NT4_T);
    IS(enc[7], ENCODED_NT4_A);

    {
        // generate kmer
        vector<KmerType> kmers;
        OK(gen_kmer_nt4(enc, kmers, 3));
        IS(kmers.size(), 6);
        IS(kmers[0], ENCODED_NT4_A + ENCODED_NT4_T*4 + ENCODED_NT4_G*4*4);
        IS(kmers[1], numeric_limits<KmerType>::max());
        IS(kmers[2], numeric_limits<KmerType>::max());
        IS(kmers[3], numeric_limits<KmerType>::max());
        IS(kmers[4], ENCODED_NT4_C + ENCODED_NT4_A*4 + ENCODED_NT4_T*4*4);
        IS(kmers[5], ENCODED_NT4_A + ENCODED_NT4_T*4 + ENCODED_NT4_A*4*4);

        // decode kmer
        IS(decode_kmer_nt4(kmers[0], 3), "ATG");
        IS(decode_kmer_nt4(kmers[1], 3), "");
        IS(decode_kmer_nt4(kmers[2], 3), "");
        IS(decode_kmer_nt4(kmers[3], 3), "");
        IS(decode_kmer_nt4(kmers[4], 3), "CAT");
        IS(decode_kmer_nt4(kmers[5], 3), "ATA");
    }

    {
        vector<KmerType> kmers;
        OK(gen_kmer_nt4(enc, kmers, 7));
        IS(kmers.size(), 2);

        KmerType kmer =
                ENCODED_NT4_A +
                ENCODED_NT4_T *4 +
                ENCODED_NT4_G *4*4 +
                ENCODED_NT4_C *4*4*4 +
                ENCODED_NT4_A *4*4*4*4 +
                ENCODED_NT4_T *4*4*4*4*4 +
                ENCODED_NT4_A *4*4*4*4*4*4;
        IS(gen_kmer_nt4<KmerType>("ATGCATA"), kmer);
    }

    {
        vector<KmerType> kmers;
        OK(!gen_kmer_nt4(enc, kmers, 8));
        IS(kmers.size(), 0);

        IS(gen_kmer_nt4<KmerType>("ATGCATAA"), numeric_limits<KmerType>::max());
    }

    // decode
    {
        string dec;
        decode_nt4(enc, dec);
        IS(dec, "ATGNCATA");
    }
}
