#include "htqc/MultiSeqFile.h"

#include "htio2/FastqSeq.h"
#include "htio2/SeqIO.h"

namespace htqc
{

MultiSeqFileSE::MultiSeqFileSE(const std::vector<std::string>& files,
                               htio2::CompressFormat comp)
: files(files)
, fh(htio2::SeqIO::New(files[0], htio2::READ, comp))
, comp(comp)
, curr_file_i(0)
{
}

MultiSeqFileSE::~MultiSeqFileSE() {}

bool MultiSeqFileSE::next_seq(htio2::FastqSeq& seq)
{
    // early out if we have reached the end
    if (curr_file_i >= files.size())
        return false;

    while (true)
    {
        // try to get next sequence
        bool re = fh->next_seq(seq);
        if (re)
            return true;

        // try the next file
        fh = nullptr;
        curr_file_i++;
        if (curr_file_i >= files.size())
            return false;

        fh = htio2::SeqIO::New(files[curr_file_i], htio2::READ, comp);
    }
}

MultiSeqFilePE::MultiSeqFilePE(const std::vector<std::string>& files,
                               htio2::Strand strand_r1_in_file,
                               htio2::Strand strand_r2_in_file,
                               htio2::CompressFormat comp)
: files_a(files)
, fh(new htio2::PairedEndIO(files[0],
                           htio2::READ,
                           strand_r1_in_file,
                           strand_r2_in_file,
                           comp,
                           htio2::FORMAT_UNKNOWN))
, interleave(true)
, strand_r1_in_file(strand_r1_in_file)
, strand_r2_in_file(strand_r2_in_file)
, comp(comp)
, curr_file_i(0)
{
}

MultiSeqFilePE::MultiSeqFilePE(const std::vector<std::string>& files_a,
                               const std::vector<std::string>& files_b,
                               htio2::Strand strand_r1_in_file,
                               htio2::Strand strand_r2_in_file,
                               htio2::CompressFormat comp)
: files_a(files_a)
, files_b(files_b)
, fh(new htio2::PairedEndIO(files_a[0],
                           files_b[0],
                           htio2::READ,
                           strand_r1_in_file,
                           strand_r2_in_file,
                           comp,
                           htio2::FORMAT_UNKNOWN))
, interleave(false)
, strand_r1_in_file(strand_r1_in_file)
, strand_r2_in_file(strand_r2_in_file)
, comp(comp)
, curr_file_i(0)
{
}

MultiSeqFilePE::~MultiSeqFilePE() {}

bool MultiSeqFilePE::next_pair(htio2::FastqSeq& seq1,
                               htio2::FastqSeq& seq2,
                               htio2::Strand strand_r1,
                               htio2::Strand strand_r2)
{
    if (curr_file_i >= files_a.size())
        return false;

    while (true)
    {
        bool re = fh->next_pair(seq1, seq2, strand_r1, strand_r2);
        if (re)
            return true;

        delete fh;
        curr_file_i++;
        if (curr_file_i >= files_a.size())
            return false;

        fh = interleave
            ? new htio2::PairedEndIO(files_a[curr_file_i],
                                    htio2::READ,
                                    strand_r1_in_file,
                                    strand_r2_in_file,
                                    comp,
                                    htio2::FORMAT_UNKNOWN)
            : new htio2::PairedEndIO(files_a[curr_file_i],
                                    files_b[curr_file_i],
                                    htio2::READ,
                                    strand_r1_in_file,
                                    strand_r2_in_file,
                                    comp,
                                    htio2::FORMAT_UNKNOWN);
    }
}
} // namespace htqc

