/**
 * \file pappsomspp/masschroq/mbrpeptidemeasurements.cpp
 * \date 27/10/2024
 * \author Olivier Langella
 * \brief peptide extracted measures in MBR mode model in masschroqlite
 */

/*******************************************************************************
 * Copyright (c) 2024 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 "mbrpeptidemeasurements.h"

#include "msrungroup.h"
#include "pappsomspp/core/processing/detection/tracepeaklist.h"
#include "pappsomspp/core/pappsoexception.h"

pappso::masschroq::MbrPeptideMeasurements::MbrPeptideMeasurements(
  const pappso::masschroq::PeptideSp &peptide_sp)
  : msp_peptide(peptide_sp)
{
  if(msp_peptide.get() == nullptr)
    {
      throw pappso::PappsoException("msp_peptide.get() == nullptr");
    }
}


pappso::masschroq::MbrPeptideMeasurements::MbrPeptideMeasurements(
  const pappso::masschroq::MbrPeptideMeasurements &other)
  : PeptideMeasurementsBase(other)
{
  msp_peptide                 = other.msp_peptide;
  m_consensusMs2RetentionTime = other.m_consensusMs2RetentionTime;
}


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


void
pappso::masschroq::MbrPeptideMeasurements::prepareMeasurements(
  const pappso::MsRunId &targeted_msrun,
  const pappso::masschroq::MsRunGroup *msrun_group_p,
  const pappso::MsRunRetentionTime<QString> &msrun_retention_time,
  const QuantificationMethodSp &quantification_method)
{
  // for one peptide
  pappso::masschroq::Peptide *the_peptide_p = msp_peptide.get();
  //  1) charge states
  //  2) isotope list
  std::vector<std::uint8_t> charge_states = the_peptide_p->getAllObservedChargeStateList();


  m_consensusMs2RetentionTime = the_peptide_p->getConsensusMs2RetentionTime();

  if(msrun_retention_time.isAligned())
    {
      m_consensusMs2RetentionTime =
        msrun_retention_time.translateAligned2OriginalRetentionTime(m_consensusMs2RetentionTime);
    }

  double consensus_rt = the_peptide_p->getConsensusPeakRetentionTime();

  if(consensus_rt > 0)
    {
      if(msrun_retention_time.isAligned())
        {
          consensus_rt = msrun_retention_time.translateAligned2OriginalRetentionTime(consensus_rt);
        }
    }
  for(std::uint8_t charge : charge_states)
    {

      pappso::XicCoordSPtr best_xic_coord;
      if(msrun_group_p->getIonMobilityGridSp().get() != nullptr)
        {
          best_xic_coord = the_peptide_p->getBestIonMobilityXicCoordToExtractOverallMsRunGroup(
            *msrun_group_p, targeted_msrun, charge);
        }
      else
        {
          best_xic_coord =
            the_peptide_p->getBestXicCoordSPtrForChargeInMsRunGroup(msrun_group_p, charge);
        }

      if(best_xic_coord.get() == nullptr)
        {
          // We can not quantify it in this msrun group
        }
      else
        {

          prepareMeasurementsForPeptide(
            *the_peptide_p, quantification_method, best_xic_coord, charge, consensus_rt);
        }
    }
}


void
pappso::masschroq::MbrPeptideMeasurements::detectQuantifyPeaks(
  const pappso::masschroq::QuantificationMethodSp &quantification_method)
{

  qDebug();
  pappso::TracePeakList peak_list;
  std::vector<std::uint8_t> all_charge_states = msp_peptide.get()->getAllObservedChargeStateList();


  for(auto &measure_one : m_measurementList)
    {
      qDebug();
      double rt_target = measure_one.msp_xicCoord.get()->rtTarget;
      peak_list.clear();
      quantification_method.get()->getTraceDetectionInterfaceCstSPtr().get()->detect(
        *(measure_one.msp_xicCoord.get()->xicSptr.get()), peak_list, false);

      qDebug();
      measure_one.m_peakQualityCategory = PeakQualityCategory::missed;
      if(m_consensusMs2RetentionTime > 0)
        {
          qDebug();
          auto it_best_matched_peak = pappso::findTracePeakGivenRt(
            peak_list.begin(), peak_list.end(), m_consensusMs2RetentionTime);

          if(it_best_matched_peak != peak_list.end())
            {
              measure_one.m_tracePeakSp         = it_best_matched_peak->makeTracePeakCstSPtr();
              measure_one.m_peakQualityCategory = PeakQualityCategory::c;
              if(it_best_matched_peak->containsRt(rt_target))
                {
                  measure_one.m_peakQualityCategory = PeakQualityCategory::b;
                }
            }
          else
            {

              it_best_matched_peak =
                pappso::findTracePeakGivenRt(peak_list.begin(), peak_list.end(), rt_target);

              if(it_best_matched_peak != peak_list.end())
                {
                  measure_one.m_tracePeakSp         = it_best_matched_peak->makeTracePeakCstSPtr();
                  measure_one.m_peakQualityCategory = PeakQualityCategory::d;
                }
            }
        }
    }
}

const pappso::masschroq::PeptideSp &
pappso::masschroq::MbrPeptideMeasurements::getPeptideSp() const
{
  return msp_peptide;
}
