


/*******************************************************************************
 * Copyright (c) 2025 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ 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.
 *
 *     PAPPSOms++ 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 PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/


// ./tests/proteincode/catch2-only-proteincode [zea4291] -s


//    msconvert
//    /gorgone/pappso/formation/Janvier2014/TD/mzXML/20120906_balliau_extract_1_A01_urnb-1.mzXML
//    --filter "index 4291" --mgf

#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp>

#include <QDebug>
#include <pappsomspp/core/exception/exceptionnotfound.h>
#include <pappsomspp/core/exception/exceptionoutofrange.h>
#include <pappsomspp/core/peptide/peptideproformaparser.h>
#include <pappsomspp/core/protein/protein.h>
#include <pappsomspp/core/protein/proteinintegercode.h>
#include <pappsomspp/core/protein/proteinpresenceabsencematrix.h>
#include <pappsomspp/core/massspectrum/qualifiedmassspectrum.h>
#include <pappsomspp/core/processing/filters/filterresample.h>
#include <pappsomspp/core/processing/filters/filterpass.h>
#include <pappsomspp/core/processing/filters/filterchargedeconvolution.h>
#include <pappsomspp/core/processing/filters/filterpeakdelta.h>
#include <pappsomspp/core/amino_acid/aastringcodemassmatching.h>
#include <pappsomspp/core/fasta/fastareader.h>
#include "proteincode_lib.h"
#include "../common.h"
#include "tests/tests-config.h"


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


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


    // instead of QQVM[MOD:00425]VGYSDSGK from GRMZM2G083841_P01
    /*
     *

{"id":{
    "index": 3624,
    "native_id": "controllerType=0 controllerNumber=1 scan=3625"
}
[
{"proforma":"MATAPSDVLAVELLQRECGVRQPLPVVPLFERLADLQSAPASVERLFSVDWYMDRIKGKQQVMVGYSDSGKDAGRLSAAWQLYRAQEEMAQVAKRYGVKLTLFH",
"protein_list":
[{
    "accession": "GRMZM2G083841_P01",
    "positions": [
        535
    ]
}
]
,
"eval":{
    "matcher": {
        "score": 415549
    }
}
}
*/

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

    pappso::MassSpectrum spectrum =
      readMgf(QString(CMAKE_SOURCE_DIR)
                .append("/tests/data/scans/"
                        "20120906_balliau_extract_1_A08_teal-2_scan_3302.mgf"));


    pappso::FilterResampleKeepGreater(160).filter(spectrum);
    pappso::FilterChargeDeconvolution(pappso::PrecisionFactory::getDaltonInstance(0.02))
      .filter(spectrum);
    //.applyCutOff(150).takeNmostIntense(100).applyDynamicRange(100);
    pappso::FilterGreatestY(100).filter(spectrum);

    pappso::FilterPeakDelta filter_peak_delta;
    filter_peak_delta.filter(spectrum);

    pappso::FilterGreatestY(200).filter(spectrum);
    std::vector<double> delta_mass_list = spectrum.xValues();


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

    Protein protein("GRMZM2G083841_P01",
                    "MATAPSDVLAVELLQRECGVRQPLPVVPLFERLADLQSAPASVERLFSVDWYMDRIKGKQQVMVGYSDSGKDAGRLSA"
                    "AWQLYRAQEEMAQVAKRYGVKLTLFH");

    pappso::ProteinIntegerCode protein_integer_code(
      {std::make_shared<Protein>(protein), aa_codec, 5});


    pappso::AaStringCodeMassMatching aaMatching(
      aa_code, 7, pappso::PrecisionFactory::getDaltonInstance(0.01));

    std::vector<uint32_t> code_list_from_spectrum =
      aaMatching.getAaCodeFromMassList(delta_mass_list);


    std::sort(code_list_from_spectrum.begin(), code_list_from_spectrum.end());
    code_list_from_spectrum.erase(
      std::unique(code_list_from_spectrum.begin(), code_list_from_spectrum.end()),
      code_list_from_spectrum.end());

    std::vector<double> convolution_score;
    pappso::ProteinPresenceAbsenceMatrix presence_absence_matrix;
    pappso::ProteinPresenceAbsenceMatrix best_presencce_absence_matrix;


    presence_absence_matrix.fillMatrix(protein_integer_code, code_list_from_spectrum);

    // qDebug() << protein_sp.get()->getAccession();
    std::vector<double> vec_score = presence_absence_matrix.convolution();
    auto it_score                 = std::max_element(vec_score.begin(), vec_score.end());

    // double score = std::accumulate(it_score - 2, it_score + 5, 0);

    double max_score=0;
    if(it_score != vec_score.end())
      {
        // std::cout << protein_sp.get()->getAccession().toStdString() << "
        // "
        //         << score << std::endl;
        double score = std::accumulate(it_score - 2, it_score + 5, 0);
        if(score > max_score)
          {
            max_score                     = score;
            convolution_score             = vec_score;
            best_presencce_absence_matrix = presence_absence_matrix;

          }
      }

      REQUIRE(max_score == 402054.0);

    writeProteinConvolutionScore("best_fit_scan_4291.ods",
                                 protein,
                                 &best_presencce_absence_matrix,
                                 convolution_score);
    qDebug();
    // REQUIRE(locations.size() == 0);
  }
}
