
//
// File: benchmark_mzcbor.cpp
// Created by: Olivier Langella
// Created on: 22/12/2025
//
/*******************************************************************************
 * 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/benchmark/catch2-benchmark-tests [spoms] -s --benchmark-samples 5
// --benchmark-resamples 1 --benchmark-confidence-interval 0

#include <catch2/catch_test_macros.hpp>
#include <catch2/benchmark/catch_benchmark.hpp>
#include <pappsomspp/core/amino_acid/aacode.h>
#include <pappsomspp/core/amino_acid/aamodification.h>
#include <pappsomspp/core/fasta/fastareader.h>
#include <pappsomspp/core/exception/exceptionoutofrange.h>
#include <QDebug>
#include "../config.h"
#include "../common.h"
#include "../../src/core/spoms/protein_list.h"
#include "../../src/core/spoms/transformedspectrum.h"
#include "../../src/core/spoms/locationbackup.h"
#include "../../src/core/spoms/spomsutils.h"


class FastaSeqHandlerLocalSpoms : public pappso::FastaHandlerInterface
{
  public:
  FastaSeqHandlerLocalSpoms(pappso::AaCode *aa_code)
  {
    mp_aaCode       = aa_code;
    mpa_proteinList = new pappso::spoms::ProteinList(*mp_aaCode);
  }
  void
  setSequence(const QString &description_in,
              const QString &sequence_in) override
  {
    QString sequence = sequence_in.trimmed().simplified();
    if(!sequence.contains("X"))
      {
        pappso::ProteinSp protein_sp =
          std::make_shared<pappso::Protein>(description_in, sequence_in);

        mpa_proteinList->addProtein(protein_sp);
      }
  };

  pappso::spoms::ProteinList &
  getProteinList()
  {
    return *mpa_proteinList;
  };

  private:
  pappso::AaCode *mp_aaCode;
  pappso::spoms::ProteinList *mpa_proteinList;
};


TEST_CASE("cbor psm map test suite.", "[spoms]")
{
  // Set the debugging message formatting pattern.
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));


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


  pappso::QualifiedMassSpectrum spectrum_simple =
    readMgf(QString(CMAKE_SOURCE_DIR)
              .append("/tests/data/peaklists/peaklist_15046.mgf"));

  QualifiedMassSpectrumCstSPtr qmsp =
    spectrum_simple.makeQualifiedMassSpectrumCstSPtr();

  std::shared_ptr<const pappso::spoms::TransformedSpectrum>
    transformed_spectrum_sp =
      std::make_shared<const pappso::spoms::TransformedSpectrum>(aa_code, qmsp);


  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "post_treatment", "shut_down_peaks_cleaning", true);
  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "post_treatment", "shut_down_non_aligned_mass", true);
  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "alignment", "nb_locations_saved", 5);
  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "spectrum", "n_most_intense", 120);
  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "spectrum", "deisotope", false);
  spoms::SpomsUtils::GetInstance()->setParameterValue(
    "spectrum", "minimum_mz", 0.0);

  SECTION("..:: PSM cbor features::..", "[spoms]")
  {

    BENCHMARK("transformed spectrum construction")
    {
      std::shared_ptr<const pappso::spoms::TransformedSpectrum>
        transformed_spectrum_sp_test =
          std::make_shared<const pappso::spoms::TransformedSpectrum>(aa_code,
                                                                     qmsp);
    };
    // qDebug() << "Completed fastAlign";
  }

  SECTION("..:: PSM cbor features::..", "[spoms]")
  {

    FastaSeqHandlerLocalSpoms seq_handler(&aa_code);
    pappso::FastaReader fasta_reader(seq_handler);
    QFile fasta(QString(CMAKE_SOURCE_DIR)
                  .append("/tests/data/fasta/very_small_zea_mays.fasta"));
    fasta_reader.parse(fasta);

    auto score_grid =
      pappso::spoms::SpomsUtils::GetInstance()->getAlignmentScoreGrid();

    BENCHMARK("fastAlign on all protein very_small_zea_mays.fasta")
    {

      std::vector<pappso::spoms::LocationBackup> location_list;
      for(const auto &protein : seq_handler.getProteinList().getProteinList())
        {
          location_list = protein.get()->preliminaryTreatmentV1(
            *transformed_spectrum_sp.get(), aa_code, 30, score_grid);
        }
    };
    // qDebug() << "Completed fastAlign";
  }


  SECTION("..:: PSM cbor features::..", "[spoms]")
  {


    FastaSeqHandlerLocalSpoms seq_handler(&aa_code);
    pappso::FastaReader fasta_reader(seq_handler);
    QFile fasta(QString(CMAKE_SOURCE_DIR)
                  .append("/tests/data/fasta/small_zea_mays.fasta"));
    fasta_reader.parse(fasta);

    REQUIRE(spoms::SpomsUtils::GetInstance()
              ->getParameterValue("alignment", "nb_locations_saved")
              .toInt() == 5);
    auto score_grid =
      pappso::spoms::SpomsUtils::GetInstance()->getAlignmentScoreGrid();

    BENCHMARK("fastAlign on all protein small_zea_mays.fasta")
    {

      std::vector<pappso::spoms::LocationBackup> location_list;
      for(const auto &protein : seq_handler.getProteinList().getProteinList())
        {
          location_list = protein.get()->preliminaryTreatmentV1(
            *transformed_spectrum_sp.get(), aa_code, 30, score_grid);
        }
    };
    // qDebug() << "Completed fastAlign";
  }
}
