/**
 * UGENE - Integrated Bioinformatics Tools.
 * Copyright (C) 2008-2024 UniPro <ugene@unipro.ru>
 * http://ugene.net
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include "GTTestsBowtie2.h"

#include <U2Core/U2SafePoints.h>

#include "GTUtilsTaskTreeView.h"
#include "primitives/GTMenu.h"
#include "runnables/ugene/corelibs/U2Gui/AlignShortReadsDialogFiller.h"
#include "runnables/ugene/corelibs/U2Gui/BuildIndexDialogFiller.h"
#include "runnables/ugene/corelibs/U2Gui/ImportBAMFileDialogFiller.h"
#include "system/GTFile.h"
#include "utils/GTUtilsDialog.h"

namespace U2 {
namespace GUITest_Bowtie2 {

GUI_TEST_CLASS_DEFINITION(test_0001) {
    // 1. {Tools -> Align to reference -> build index}
    // 2. Fill the dialog:
    //   {Align short reads method} : Bowtie2
    //   {Reference sequence} : _common_data/fasta/human_T1_cutted.fa
    //   {Index file name} : _tmp/bowtie2/human_T1_cutted
    //  And click Start.
    GTUtilsDialog::waitForDialog(new BuildIndexDialogFiller(testDir + "_common_data/fasta/", "human_T1_cutted.fa", "Bowtie2", false, testDir + "_common_data/scenarios/sandbox/", "human_T1_cutted"));

    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Build index for reads mapping..."});

    // Expected state: there are six files as result:
    // human_T1_cutted.1.bt2, human_T1_cutted.2.bt2, human_T1_cutted.3.bt2, human_T1_cutted.4.bt2,
    // human_T1_cutted.rev.1.bt2, human_T1_cutted.rev.2.bt2
    QStringList indexList;
    for (int i = 0; i < 4; i++) {
        indexList << testDir + "_common_data/scenarios/sandbox/human_T1_cutted." + QString::number(i + 1) + ".bt2";
    }
    indexList << testDir + "_common_data/scenarios/sandbox/human_T1_cutted.rev.1.bt2";
    indexList << testDir + "_common_data/scenarios/sandbox/human_T1_cutted.rev.2.bt2";

    for (int i = 0; i < indexList.size(); i++) {
        CHECK_SET_ERR(GTFile::check(indexList[i]), "Index file " + indexList[i] + " is missing!");
    }
}

GUI_TEST_CLASS_DEFINITION(test_0002) {
    // Align short reads with bowtie2
    // no prebuilt index, default settings
    // The settings defined here could be used as default in other tests

    // 1. {Tools -> Align to reference -> Align short reads}

    // 2. Fill the dialog:
    //     {Mapping tool} : Bowtie2
    //     {Reference sequence} : _common_data/fasta/human_T1_cutted.fa
    //     {Result file name} : _tmp/bowtie2/human_T1_cutted.sam
    //     {Library} : single-end
    //     {Prebuilt index} : unchecked
    //     {Short reads} : _common_data/fasta/shuffled.fa

    // Parameters:
    //     {Mode} : --end-to-end
    //     {Number of mismatches} : 0
    //     {Seed length (--L)} : unchecked (20)
    //     {Add columns to allow gaps (--dpad)} : unchecked (15)
    //     {Disallow gaps (--gbar)} : unchecked (4)
    //     {Seed (--seed)} : unchecked (0)
    //     {Threads} : 4 (depends on CPU cores)

    // Flags:
    //     {No unpaired alignments (--no-mixed)} : unchecked
    //     {No discordant alignments (--no-discordant)} : unchecked
    //     {No forward orientation (--nofw)} : unchecked
    //     {No reverse-complement orientation (--norc)} : unchecked
    //     {No overlapping mates (--no-overlap)} : unchecked
    //     {No mates containing one another (--no-contain)} : unchecked

    // And click Start.
    // Expected state: an "Import SAM file" dialog appears. The incoming assembly has name "human_T1" and contains 3 reads.
    GTFile::copy(testDir + "_common_data/bowtie2/index/human_T1_cutted.fa", testDir + "_common_data/scenarios/sandbox/human_T1_cutted.fa");

    AlignShortReadsFiller::Bowtie2Parameters bowtie2Parameters(testDir + "_common_data/scenarios/sandbox/",
                                                               "human_T1_cutted.fa",
                                                               testDir + "_common_data/fasta/",
                                                               "shuffled.fa");
    // Parameters
    AlignShortReadsFiller* alignShortReadsFiller = new AlignShortReadsFiller(&bowtie2Parameters);

    GTUtilsDialog::add(alignShortReadsFiller);

    ImportBAMFileFiller* importBAMFileFiller = new ImportBAMFileFiller();

    GTUtilsDialog::add(importBAMFileFiller);

    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Map reads to reference..."});

    GTUtilsTaskTreeView::waitTaskFinished();
}

GUI_TEST_CLASS_DEFINITION(test_0003) {
    //    File will be copied to the sandbox
    //    1. {Tools -> Align to reference -> Align short reads}
    //    2. Fill the dialog:
    //        {Mapping tool} : Bowtie2
    //        {Reference sequence} : _common_data/bowtie2/index/human_T1_cutted.fa
    //        {Result file name} : _tmp/bowtie2/human_T1_cutted.sam (in current test result path is default)
    //        {Library} : single-end
    //        {Prebuilt index} : unchecked
    //        {Short reads} : _common_data/fasta/shuffled.fa

    //    Parameters:
    //        {Mode} : --end-to-end
    //        {Number of mismatches} : 0
    //        {Seed length (--L)} : checked (20)
    //        {Add columns to allow gaps (--dpad)} : checked (15)
    //        {Disallow gaps (--gbar)} : checked (4)
    //        {Seed (--seed)} : checked (0)
    //        {Threads} : 4 (depends on CPU cores)

    //    Flags:
    //        {No unpaired alignments (--no-mixed)} : checked
    //        {No discordant alignments (--no-discordant)} : checked
    //        {No forward orientation (--nofw)} : checked
    //        {No reverse-complement orientation (--norc)} : checked
    //        {No overlapping mates (--no-overlap)} : checked
    //        {No mates containing one another (--no-contain)} : checked
    GTFile::copy(testDir + "_common_data/bowtie2/index/human_T1_cutted.fa", testDir + "_common_data/scenarios/sandbox/human_T1_cutted.fa");

    AlignShortReadsFiller::Bowtie2Parameters bowtie2Parameters(testDir + "_common_data/scenarios/sandbox/",
                                                               "human_T1_cutted.fa",
                                                               testDir + "_common_data/fasta/",
                                                               "shuffled.fa");

    // Parameters
    bowtie2Parameters.seedLengthCheckBox = true;
    bowtie2Parameters.addColumnsToAllowGapsCheckBox = true;
    bowtie2Parameters.disallowGapsCheckBox = true;
    bowtie2Parameters.seedCheckBox = true;

    // Flags
    bowtie2Parameters.noUnpairedAlignments = true;
    bowtie2Parameters.noDiscordantAlignments = true;
    bowtie2Parameters.noForwardOrientation = true;
    bowtie2Parameters.noReverseComplementOrientation = true;
    bowtie2Parameters.noOverlappingMates = true;
    bowtie2Parameters.noMatesContainingOneAnother = true;

    AlignShortReadsFiller* alignShortReadsFiller = new AlignShortReadsFiller(&bowtie2Parameters);

    GTUtilsDialog::add(alignShortReadsFiller);

    ImportBAMFileFiller* importBAMFileFiller = new ImportBAMFileFiller();

    GTUtilsDialog::add(importBAMFileFiller);

    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Map reads to reference..."});

    GTUtilsTaskTreeView::waitTaskFinished();
}

GUI_TEST_CLASS_DEFINITION(test_0004) {
    //    File will be copied to the sandbox
    //    1. {Tools -> Align to reference -> Align short reads}
    //    2. Fill the dialog:
    //        {Mapping tool} : Bowtie2
    //        {Reference sequence} : _common_data/bowtie2/index/human_T1_cutted.fa
    //        {Library} : single-end
    //        {Prebuilt index} : unchecked
    //        {Short reads} : _common_data/fasta/shuffled.fa

    //    Parameters:
    //        {Mode} : --local
    //        {Number of mismatches} : 1
    //        {Seed length (--L)} : checked (24)
    //        {Add columns to allow gaps (--dpad)} : checked (13)
    //        {Disallow gaps (--gbar)} : checked (5)
    //        {Seed (--seed)} : checked (23)
    //        {Threads} : 3 (depends on CPU cores)

    //    Flags:
    //        {No unpaired alignments (--no-mixed)} : checked
    //        {No discordant alignments (--no-discordant)} : unchecked
    //        {No forward orientation (--nofw)} : unchecked
    //        {No reverse-complement orientation (--norc)} : checked
    //        {No overlapping mates (--no-overlap)} : checked
    //        {No mates containing one another (--no-contain)} : unchecked

    GTFile::copy(testDir + "_common_data/bowtie2/index/human_T1_cutted.fa", testDir + "_common_data/scenarios/sandbox/human_T1_cutted.fa");

    AlignShortReadsFiller::Bowtie2Parameters bowtie2Parameters(testDir + "_common_data/bowtie2/index",
                                                               "human_T1_cutted.fa",
                                                               testDir + "_common_data/fasta",
                                                               "shuffled.fa");

    // Parameters
    bowtie2Parameters.mode = AlignShortReadsFiller::Bowtie2Parameters::Local;
    bowtie2Parameters.numberOfMismatches = 1;
    bowtie2Parameters.seedLengthCheckBox = true;
    bowtie2Parameters.seedLength = 24;
    bowtie2Parameters.addColumnsToAllowGapsCheckBox = true;
    bowtie2Parameters.addColumnsToAllowGaps = 13;
    bowtie2Parameters.disallowGapsCheckBox = true;
    bowtie2Parameters.disallowGaps = 5;
    bowtie2Parameters.seedCheckBox = true;
    bowtie2Parameters.seed = 23;
    bowtie2Parameters.threads = 3;

    // Flags
    bowtie2Parameters.noUnpairedAlignments = true;
    bowtie2Parameters.noDiscordantAlignments = false;
    bowtie2Parameters.noForwardOrientation = false;
    bowtie2Parameters.noReverseComplementOrientation = true;
    bowtie2Parameters.noOverlappingMates = false;
    bowtie2Parameters.noMatesContainingOneAnother = false;

    GTUtilsDialog::add(new AlignShortReadsFiller(&bowtie2Parameters));
    GTUtilsDialog::add(new ImportBAMFileFiller(testDir + "_common_data/scenarios/sandbox/human_T1_cutted.sam.ugenedb"));

    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Map reads to reference..."});

    GTUtilsTaskTreeView::waitTaskFinished();
}

GUI_TEST_CLASS_DEFINITION(test_0005) {
    AlignShortReadsFiller::Bowtie2Parameters bowtie2Parameters(testDir + "_common_data/scenarios/assembly/bowtie2/index/",
                                                               "e_coli_1000.1.bt2",
                                                               testDir + "_common_data/scenarios/assembly/bowtie2/",
                                                               "e_coli_1000.fq");
    bowtie2Parameters.prebuiltIndex = true;
    GTUtilsDialog::add(new AlignShortReadsFiller(&bowtie2Parameters));
    GTUtilsDialog::add(new ImportBAMFileFiller());
    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Map reads to reference..."});

    GTUtilsTaskTreeView::waitTaskFinished();
}

GUI_TEST_CLASS_DEFINITION(test_0006) {
    AlignShortReadsFiller::Bowtie2Parameters parameters(testDir + "_common_data/bowtie2/",
                                                        "lambda_virus.fa.gz",
                                                        testDir + "_common_data/bowtie2/",
                                                        "reads_1.fq");
    GTUtilsDialog::waitForDialog(new AlignShortReadsFiller(&parameters));
    GTMenu::clickMainMenuItem({"Tools", "NGS data analysis", "Map reads to reference..."});

    GTUtilsDialog::waitForDialog(new ImportBAMFileFiller());
    GTUtilsTaskTreeView::waitTaskFinished();
}

}  // namespace GUITest_Bowtie2
}  // namespace U2
