/**
 * \file pappsomspp/processing/cbor/psm/evalscan/psmspecglob.cpp
 * \date 19/07/2025
 * \author Olivier Langella
 * \brief compute specglob alignment on scan's PSM
 */

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

#include "psmspecglob.h"
#include "psmspecglobscan.h"
#include "pappsomspp/core/processing/filters/filtersuitestring.h"
#include "pappsomspp/core/processing/filters/filterresample.h"
#include "pappsomspp/core/processing/filters/filterpass.h"
#include "pappsomspp/core/processing/filters/filterchargedeconvolution.h"

pappso::cbor::psm::PsmSpecGlob::PsmSpecGlob(std::size_t buffer_scan_size,
                                            pappso::cbor::CborStreamWriter *cbor_output_p,
                                            const QJsonObject &parameters)
  : PsmFileScanProcessAndCopy(buffer_scan_size, cbor_output_p, "SpecGlob")
{
  qDebug();
  m_specglobParameters = parameters;

  if(parameters.value("fragment_tolerance_unit").toString() == "dalton")
    {
      m_fragmentTolerance = pappso::PrecisionFactory::getDaltonInstance(
        parameters.value("fragment_tolerance").toDouble());
    }
  else if(parameters.value("fragment_tolerance_unit").toString() == "ppm")
    {
      m_fragmentTolerance =
        pappso::PrecisionFactory::getPpmInstance(parameters.value("fragment_tolerance").toDouble());
    }

  QJsonObject spectrum_param = parameters.value("spectrum").toObject();

  m_minimumMz    = spectrum_param.value("minimum_mz").toDouble();
  m_nMostIntense = spectrum_param.value("n_most_intense").toInt();
  m_deisotope    = spectrum_param.value("deisotope").toBool();
  qDebug();
}

pappso::cbor::psm::PsmSpecGlob::~PsmSpecGlob()
{
}

void
pappso::cbor::psm::PsmSpecGlob::parameterMapReady(pappso::UiMonitorInterface &monitor
                                                  [[maybe_unused]])
{
  qDebug();
  QCborMap cbor_specglob_parameters = QCborValue::fromJsonValue(m_specglobParameters).toMap();


  if(m_cborParameterMap.contains(QString("matcher")))
    {
      m_isProteinMatcherResult = true;
    }

  m_cborParameterMap.insert(QString("specglob"), cbor_specglob_parameters);


  mp_cborOutput->append("parameter_map");
  mp_cborOutput->writeCborMap(m_cborParameterMap);
  qDebug();
}


void
pappso::cbor::psm::PsmSpecGlob::filterMassSpectrum(pappso::MassSpectrum &mass_spectrum) const
{
  if(m_deisotope)
    pappso::FilterChargeDeconvolution(m_fragmentTolerance).filter(mass_spectrum);
  pappso::FilterResampleKeepGreater(m_minimumMz).filter(mass_spectrum);
  pappso::FilterGreatestY(m_nMostIntense).filter(mass_spectrum);
}


pappso::cbor::psm::CborScanMapBase *
pappso::cbor::psm::PsmSpecGlob::newCborScanMap()
{

  return new PsmSpecGlobScan(*this, m_fragmentTolerance);
}


void
pappso::cbor::psm::PsmSpecGlob::processBufferScanDone(pappso::UiMonitorInterface &monitor)
{


  PsmFileScanProcessAndCopy::processBufferScanDone(monitor);
  m_countScanProcessed += m_bufferScanSize;

  monitor.setStatus(QObject::tr("%1 scan processed").arg(m_countScanProcessed));
}
