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

#define USE_prefix_out
#define USE_se_pe
#include "htqc/Options.h"
#include "htqc/App.h"
#include "htqc/MultiSeqFile.h"

#include <sstream>

using namespace std;
using namespace htqc;

#define OPTION_GROUP_NAMING "Naming Options"

string OPT_name_prefix;
htio2::Option OPT_name_prefix_ENTRY("prefix", '\0', OPTION_GROUP_NAMING,
                                    &OPT_name_prefix, htio2::Option::FLAG_NONE,
                                    "Prefix for generated IDs.", "STRING");

string OPT_name_suffix;
htio2::Option OPT_name_suffix_ENTRY("suffix", '\0', OPTION_GROUP_NAMING,
                                    &OPT_name_suffix, htio2::Option::FLAG_NONE,
                                    "Suffix for generated IDs.", "STRING");

bool keep_desc;
htio2::Option OPT_keep_desc_ENTRY("keep-desc", '\0', OPTION_GROUP_NAMING,
                                  &keep_desc, htio2::Option::FLAG_NONE,
                                  "Keep description of the input sequences, which is the header content after first continuous blank.");

void parse_options(int argc, char** argv)
{
    OPT_se = true;

    htio2::OptionParser opt_psr;
    opt_psr.add_option(OPT_files_in_ENTRY);
    opt_psr.add_option(OPT_prefix_out_ENTRY);

    opt_psr.add_option(OPT_name_prefix_ENTRY);
    opt_psr.add_option(OPT_name_suffix_ENTRY);
    opt_psr.add_option(OPT_keep_desc_ENTRY);

    opt_psr.add_option(OPT_quiet_ENTRY);
    opt_psr.add_option(OPT_help_ENTRY);
    opt_psr.add_option(OPT_version_ENTRY);

    opt_psr.parse_options(argc, argv);

    //
    // show help
    //
    if (OPT_help)
    {
        cout << endl
            << argv[0] << " - generate simple sequence IDs by batch"
            << endl << endl
            << opt_psr.format_document();
        exit(EXIT_SUCCESS);
    }

    if (OPT_version) show_version_and_exit();
}

void validate_options()
{
    ensure_files_in();
    ensure_prefix_out();

    if (OPT_name_prefix.length() == 0 && OPT_name_suffix.length() == 0)
        cerr << "WARNING: neither prefix nor suffix was provided!" << endl;
}

void show_options()
{
    show_files_in();
    show_prefix_out();
    cout << "# ID format: " << OPT_name_prefix << "(NUMBER)" << OPT_name_suffix;
    if (keep_desc) cout << " DESCRIPTION";
    cout << endl;
}

void execute()
{
    // output handle
    string file_out;
    add_fastq_suffix_se(OPT_prefix_out, OPT_compress, file_out);
    check_output_overwrite(OPT_files_in, file_out);
    htio2::SeqIO::Ptr fh_out(htio2::SeqIO::New(file_out, htio2::WRITE, OPT_compress));

    // traverse input files
    if (!OPT_quiet) cout << "process sequences" << endl;
    size_t num_seq = 0;
    htio2::FastqSeq curr_seq;
    htqc::MultiSeqFileSE fh_in(OPT_files_in, OPT_compress);

    while (fh_in.next_seq(curr_seq))
    {
        num_seq++;
        if (!OPT_quiet && num_seq % LOG_BLOCK == 0)
            cout << "    " << num_seq << " sequences processed" << endl;

        ostringstream id_new;
        id_new << OPT_name_prefix << num_seq << OPT_name_suffix;

        curr_seq.id = id_new.str();
        if (!keep_desc)
            curr_seq.desc = "";

        fh_out->write_seq(curr_seq);
    }

    if (!OPT_quiet) cout << "  " << num_seq << " sequences processed" << endl;
}
