/**
 * \file pappsomspp/masschroq/peptidemeasurements.cpp
 * \date 24/01/2025
 * \author Olivier Langella
 * \brief peptide measurement model base in masschroqlite
 */

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

#include "peptidemeasurementsbase.h"
#include "peptide.h"
#include "peptidelabel.h"
#include "pappsomspp/core/pappsoexception.h"

pappso::masschroq::PeptideMeasurementsBase::PeptideMeasurementsBase()
{
}

pappso::masschroq::PeptideMeasurementsBase::~PeptideMeasurementsBase()
{
}

pappso::masschroq::PeptideMeasurementsBase::PeptideMeasurementsBase(
  const pappso::masschroq::PeptideMeasurementsBase &other)
{
  m_measurementList = other.m_measurementList;
}


const std::vector<pappso::masschroq::PeptideMeasurementsBase::Measurement> &
pappso::masschroq::PeptideMeasurementsBase::getMeasurementList() const
{
  return m_measurementList;
}

void
pappso::masschroq::PeptideMeasurementsBase::generateMeasurementsForIsotopeList(
  pappso::masschroq::PeptideBase &peptide_base,
  const PeptideLabel *label_p,
  const pappso::masschroq::QuantificationMethodSp &quantification_method,
  std::uint8_t charge,
  double isotope_minimum_ratio,
  const pappso::XicCoordSPtr &best_xic_coord,
  double best_rt)
{

  qDebug();
  const std::vector<pappso::PeptideNaturalIsotopeAverageSp> &natural_isotope_average_list =
    peptide_base.getPeptideNaturalIsotopeAverageSpList(
      quantification_method.get()->getXicExtractionMeanPrecisionPtr(),
      charge,
      isotope_minimum_ratio);

  for(pappso::PeptideNaturalIsotopeAverageSp isotope_average_sp : natural_isotope_average_list)
    {
      pappso::XicCoordSPtr xic_coord = best_xic_coord->initializeAndClone();
      xic_coord.get()->rtTarget      = best_rt;
      xic_coord.get()->mzRange =
        quantification_method.get()->getXicExtractionMzRange(isotope_average_sp.get()->getMz());


      m_measurementList.push_back(
        {charge, xic_coord, PeakQualityCategory::nomatch, label_p, nullptr, isotope_average_sp});
    }

  qDebug() << m_measurementList.size();
}

void
pappso::masschroq::PeptideMeasurementsBase::prepareMeasurementsForPeptide(
  pappso::masschroq::Peptide &the_peptide,
  const QuantificationMethodSp &quantification_method,
  const pappso::XicCoordSPtr &best_xic_coord,
  std::uint8_t charge,
  double best_rt)
{

  double isotope_minimum_ratio = quantification_method.get()->getIsotopeMinimumRatio();


  auto label_map = the_peptide.getPeptideLabelMap();

  if(isotope_minimum_ratio > 0)
    {
      //  isotope
      if(label_map.size() > 0)
        {
          // isotope, label

          for(auto &peptide_label_pair : label_map)
            {
              // for each label
              qDebug();
              generateMeasurementsForIsotopeList(*(peptide_label_pair.second.get()),
                                                 peptide_label_pair.second.get(),
                                                 quantification_method,
                                                 charge,
                                                 isotope_minimum_ratio,
                                                 best_xic_coord,
                                                 best_rt);
            }
        }
      else
        {
          // isotope, no label
          generateMeasurementsForIsotopeList(the_peptide,
                                             nullptr,
                                             quantification_method,
                                             charge,
                                             isotope_minimum_ratio,
                                             best_xic_coord,
                                             best_rt);
        }
    }
  else
    {
      // no isotope
      if(label_map.size() > 0)
        {
          // no isotope, label
          for(auto &peptide_label_pair : label_map)
            {
              // for each label
              qDebug();
              double mz = peptide_label_pair.second->getPappsoPeptideSp().get()->getMz(charge);
              pappso::XicCoordSPtr xic_coord = best_xic_coord->initializeAndClone();
              xic_coord.get()->rtTarget      = best_rt;
              xic_coord.get()->mzRange = quantification_method.get()->getXicExtractionMzRange(mz);


              m_measurementList.push_back({charge,
                                           xic_coord,
                                           PeakQualityCategory::nomatch,
                                           peptide_label_pair.second.get(),
                                           nullptr,
                                           nullptr});
            }
        }
      else
        {
          // no isotope, no label
          double mz                      = the_peptide.getPappsoPeptideSp().get()->getMz(charge);
          pappso::XicCoordSPtr xic_coord = best_xic_coord->initializeAndClone();
          xic_coord.get()->rtTarget      = best_rt;
          xic_coord.get()->mzRange       = quantification_method.get()->getXicExtractionMzRange(mz);


          m_measurementList.push_back(
            {charge, xic_coord, PeakQualityCategory::nomatch, nullptr, nullptr, nullptr});
        }
    }
}


void
pappso::masschroq::PeptideMeasurementsBase::pushBackXicCoordList(
  std::vector<pappso::XicCoordSPtr> &xic_coord_list) const
{
  for(auto &measure : m_measurementList)
    {
      if(measure.msp_xicCoord.get()->rtTarget > 0)
        {
          xic_coord_list.push_back(measure.msp_xicCoord);
        }
    }
}


void
pappso::masschroq::PeptideMeasurementsBase::flushXics()
{

  for(auto &measure_one : m_measurementList)
    {
      measure_one.msp_xicCoord.get()->xicSptr = nullptr;
    }
}

void
pappso::masschroq::PeptideMeasurementsBase::clear()
{
  m_measurementList.clear();
}
