/**
 * \file tests/test_fine_4291.cpp
 * \date 14/11/2023
 * \author Olivier Langella
 * \brief tests for peptide model
 */


/*
 * SpecGlobTool, Spectra to peptide alignment tool
 * Copyright (C) 2023  Olivier Langella
 * <olivier.langella@universite-paris-saclay.fr>
 *
 * 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 3 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
 *   mp_parent-> along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 */
// ./tests/spoms/catch2-spoms-tests [fine4291] -s

#include <QDebug>
#include <QString>
#include <QTextStream>
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp>
#include <cstdint>
#include <pappsomspp/core/massspectrum/qualifiedmassspectrum.h>
#include <pappsomspp/core/amino_acid/aacode.h>
#include <qdebug.h>
#include "../../src/core/spoms/transformedspectrum.h"
#include "../config.h"
#include "../common.h"

TEST_CASE("test for peptidoms alignment.", "[fine4291]")
{
  // Set the debugging message formatting pattern.
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));

  SECTION("check bitwise operation", "[fine4291]")
  {

    std::uint32_t condition = 0;

    condition |= (std::uint32_t)1 << ((std::uint32_t)(1 + 2));

    REQUIRE(QString::number(condition, 2).toStdString() == "1000");


    REQUIRE_FALSE(condition & 1);

    condition |= 1;

    REQUIRE(condition & 1);
    REQUIRE(QString::number(condition, 2).toStdString() == "1001");

    condition |= (std::uint32_t)1 << ((std::uint32_t)(6 + 2));

    REQUIRE(condition & 1);
    REQUIRE(QString::number(condition, 2).toStdString() == "100001001");
  }


  SECTION(
    "..:: Check precise alignment for GRMZM2G083841_P01 on spectrum 4291 ::..",
    "[fine4291]")
  {

    pappso::QualifiedMassSpectrum spectrum_simple = readMgf(
      QString(CMAKE_SOURCE_DIR)
        .append("/tests/data/scans/"
                "20120906_balliau_extract_1_A01_urnb-1_4291_deisotope_60.mgf"));


    REQUIRE(spectrum_simple.size() == 60);

    pappso::AaCode aa_code;
    aa_code.addAaModification('C',
                              pappso::AaModification::getInstance("MOD:00397"));


    /*

        QFile
       mgf_out("20120906_balliau_extract_1_A01_urnb-1_4291_deisotope_60.mgf");
        mgf_out.open(QFile::WriteOnly);

        pappso::MgfOutput mgf_writer(&mgf_out);

        mgf_writer.write(spectrum_simple);
        */


    pappso::QualifiedMassSpectrumCstSPtr qmsp =
      spectrum_simple.makeQualifiedMassSpectrumCstSPtr();
    pappso::spoms::TransformedSpectrum tr_spectrum(aa_code, qmsp);


    const std::vector<spoms::AAPosition> spectrum_M_pos =
      tr_spectrum.getAminoAcidsPositions()[aa_code.getAaCode(
        pappso::Enums::AminoAcidChar::methionine)];
    REQUIRE(spectrum_M_pos.size() == 0);

    std::vector<spoms::AAPosition> spectrum_Y_pos =
      tr_spectrum.getAminoAcidsPositions()[18];

    REQUIRE(aa_code.getAaCode(pappso::Enums::AminoAcidChar::tyrosine) == 18);
    REQUIRE(spectrum_Y_pos.size() == 8);
    REQUIRE(spectrum_Y_pos.at(0).toString().toStdString() ==
            "(175.119 ,338.182)*1000000000000000000");

    REQUIRE(spectrum_Y_pos.at(1).toString().toStdString() ==
            "(257.124 ,420.191)*10000");
    REQUIRE(spectrum_Y_pos.at(2).toString().toStdString() ==
            "(493.221 ,656.285)*100000");
    REQUIRE(spectrum_Y_pos.at(3).toString().toStdString() ==
            "(496.262 ,659.318)*10000000001000000");
    REQUIRE(spectrum_Y_pos.at(4).toString().toStdString() ==
            "(656.285 ,819.342)*110000000000000000000");

    REQUIRE(spectrum_Y_pos.at(5).toString().toStdString() ==
            "(659.318 ,822.382)*101000000000000001000");

    REQUIRE(spectrum_Y_pos.at(6).toString().toStdString() ==
            "(895.413 ,1058.48)1");

    REQUIRE(spectrum_Y_pos.at(7).toString().toStdString() ==
            "(977.422 ,1140.48)1");
    /*
    * [Thread-0] INFO main.Main - Y: 18 8
[Thread-0] INFO main.Main - (175,12 ,338,18)*
[Thread-0] INFO main.Main - (257,12 ,420,19)*
[Thread-0] INFO main.Main - (493,22 ,656,29)*
[Thread-0] INFO main.Main - (496,26 ,659,32)*
[Thread-0] INFO main.Main - (656,29 ,819,34)*
[Thread-0] INFO main.Main - (659,32 ,822,38)*
[Thread-0] INFO main.Main - (895,41 ,1058,48)
[Thread-0] INFO main.Main - (977,42 ,1140,48)
*/


    auto spectrum_R_pos =
      tr_spectrum.getAminoAcidsPositions()[aa_code.getAaCode(
        pappso::Enums::AminoAcidChar::arginine)];

    REQUIRE(spectrum_R_pos.size() == 8);
    /*
 * [Thread-0] INFO main.Main - R: 17 8
[Thread-0] INFO main.Main - (19,02 ,175,12)*
[Thread-0] INFO main.Main - (83,02 ,239,11)
[Thread-0] INFO main.Main - (485,22 ,641,30)*
[Thread-0] INFO main.Main - (503,23 ,659,32)*
[Thread-0] INFO main.Main - (656,29 ,812,37)*
[Thread-0] INFO main.Main - (674,30 ,830,39)
[Thread-0] INFO main.Main - (1076,49 ,1232,58)*
[Thread-0] INFO main.Main - (1140,48 ,1296,59)*
*/

    REQUIRE(spectrum_R_pos.at(0).toString().toStdString() ==
            "(19.0178 ,175.119)*10");
    REQUIRE(spectrum_R_pos.at(1).toString().toStdString() ==
            "(83.019 ,239.113)1");
    REQUIRE(spectrum_R_pos.at(2).toString().toStdString() ==
            "(485.215 ,641.304)*100010000000000");
    REQUIRE(spectrum_R_pos.at(3).toString().toStdString() ==
            "(503.229 ,659.318)*1000000");
    REQUIRE(spectrum_R_pos.at(4).toString().toStdString() ==
            "(656.285 ,812.375)*110000000000000000000");
    REQUIRE(spectrum_R_pos.at(5).toString().toStdString() ==
            "(674.299 ,830.388)1");
    REQUIRE(spectrum_R_pos.at(6).toString().toStdString() ==
            "(1076.49 ,1232.58)*10000000");
    REQUIRE(spectrum_R_pos.at(7).toString().toStdString() ==
            "(1140.48 ,1296.59)*100000100000000000000");

    REQUIRE((spectrum_R_pos.at(5).getRightMass() -
             spectrum_R_pos.at(5).getLeftMass()) ==
            Catch::Approx(aa_code.getMass(aa_code.getAaCode(
                            pappso::Enums::AminoAcidChar::arginine)))
              .margin(0.02));
    /*

        int i = 0;
        for(auto complement : tr_spectrum.getComplementaryPeaks())
          {
            qDebug() << i << " " << complement.toString();
            i++;
          }*/
    /*
        REQUIRE(aa_code.getMass(
                  aa_code.getAaCode(pappso::Enums::AminoAcidChar::arginine)) ==
       0); //156.10111102565201691 REQUIRE(1296.586107 - 1140.484772 == 0); //
       156.10133500000006279
        */
  }
}
