
/*******************************************************************************
 * Copyright (c) 2016 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of XTPcpp.
 *
 *     XTPcpp 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.
 *
 *     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "identificationdatasource.h"
#include "identificationxtandemfile.h"
#include <pappsomspp/pappsoexception.h>
#include <pappsomspp/exception/exceptionnotfound.h>
#include <QFileInfo>
#include "../msrun.h"
#include "../peptideevidence.h"
#include <pappsomspp/msrun/private/timsmsrunreaderms2.h>

IdentificationDataSource::IdentificationDataSource(const QString resource_name)
{
  _resource_name = resource_name;
}

IdentificationDataSource::IdentificationDataSource(
  const IdentificationDataSource &other)
{
  _ms_run_sp      = other._ms_run_sp;
  _resource_name  = other._resource_name;
  _xml_id         = other._xml_id;
  _version        = other._version;
  _params         = other._params;
  _param_stats    = other._param_stats;
  _fastafile_list = other._fastafile_list;

  // PeptideEvidenceStore _peptide_evidence_store;
}

IdentificationDataSource::~IdentificationDataSource()
{
}

const std::map<IdentificationEngineStatistics, QVariant> &
IdentificationDataSource::getIdentificationEngineStatisticsMap() const
{
  return _param_stats;
}

const std::map<IdentificationEngineParam, QVariant> &
IdentificationDataSource::getIdentificationEngineParamMap() const
{
  return _params;
}

const PeptideEvidenceStore &
IdentificationDataSource::getPeptideEvidenceStore() const
{
  return _peptide_evidence_store;
}
PeptideEvidenceStore &
IdentificationDataSource::getPeptideEvidenceStore()
{
  return _peptide_evidence_store;
}

void
IdentificationDataSource::setXmlId(const QString xmlid)
{
  _xml_id = xmlid;
}
const QString &
IdentificationDataSource::getXmlId() const
{
  return _xml_id;
}

const QString &
IdentificationDataSource::getResourceName() const
{
  return _resource_name;
}

const QString
IdentificationDataSource::getSampleName() const
{
  return _ms_run_sp.get()->getSampleName();
}

void
IdentificationDataSource::setMsRunSp(MsRunSp ms_run_sp)
{
  _ms_run_sp = ms_run_sp;
}
MsRunSp
IdentificationDataSource::getMsRunSp() const
{
  return (_ms_run_sp);
}
void
IdentificationDataSource::setIdentificationEngine(IdentificationEngine engine)
{
  _engine = engine;
}

IdentificationEngine
IdentificationDataSource::getIdentificationEngine() const
{
  return _engine;
}
const QString
IdentificationDataSource::getIdentificationEngineName() const
{
  QString name = "unknown";
  switch(_engine)
    {
      case IdentificationEngine::XTandem:
        name = "X!Tandem";
        break;
      case IdentificationEngine::peptider:
        name = "peptider";
        break;
      case IdentificationEngine::mascot:
        name = "Mascot";
        break;

      case IdentificationEngine::OMSSA:
        name = "OMSSA";
        break;
      case IdentificationEngine::SEQUEST:
        name = "SEQUEST";
        break;
      case IdentificationEngine::Comet:
        name = "Comet";
        break;
      case IdentificationEngine::Morpheus:
        name = "Morpheus";
        break;
      case IdentificationEngine::MSGFplus:
        name = "MS-GF+";
        break;
      default:
        break;
    }
  return name;
}
const QString &
IdentificationDataSource::getIdentificationEngineVersion() const
{
  return _version;
}
void
IdentificationDataSource::setIdentificationEngineVersion(const QString &version)
{
  _version = version;
}
void
IdentificationDataSource::setIdentificationEngineParam(
  IdentificationEngineParam param, const QVariant &value)
{
  _params.insert(std::pair<IdentificationEngineParam, QVariant>(param, value));
}

const QVariant
IdentificationDataSource::getIdentificationEngineParam(
  IdentificationEngineParam param) const
{
  try
    {
      return _params.at(param);
    }
  catch(std::out_of_range &std_error)
    {
      return QVariant();
    }
}

void
IdentificationDataSource::setIdentificationEngineStatistics(
  IdentificationEngineStatistics param, const QVariant &value)
{
  _param_stats.insert(
    std::pair<IdentificationEngineStatistics, QVariant>(param, value));
}
const QVariant
IdentificationDataSource::getIdentificationEngineStatistics(
  IdentificationEngineStatistics param) const
{
  try
    {
      return _param_stats.at(param);
    }
  catch(std::out_of_range &std_error)
    {
      return QVariant();
    }
}

pappso::MassSpectrumCstSPtr
IdentificationDataSource::getMassSpectrumCstSPtr(unsigned int scan_number) const
{

  qDebug() << "scan=" << scan_number;
  if(_ms_run_sp.get()->getMzFormat() == pappso::MzFormat::MGF)
    {
      scan_number = scan_number - 1;
      qDebug() << "MGF format";
    }
  pappso::MsRunReaderSPtr msrun_reader_sp =
    _ms_run_sp.get()->getMsRunReaderSPtr();

  if(msrun_reader_sp == nullptr)
    {
      msrun_reader_sp = _ms_run_sp.get()->findMsRunFile();
      if(msrun_reader_sp == nullptr)
        {
          throw pappso::ExceptionNotFound(
            QObject::tr("mz data \"%1\" file not found")
              .arg(_ms_run_sp.get()->getFileName()));
        }
    }
  qDebug();
  msrun_reader_sp = _ms_run_sp.get()->getMsRunReaderSPtr();
  if(msrun_reader_sp == nullptr)
    {
      throw pappso::ExceptionNotFound(
        QObject::tr("mz data \"%1\" file not found")
          .arg(_ms_run_sp.get()->getFileName()));
    }


  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__  <<
  // _ms_run_sp.get()->getMsRunReaderSp().get()->getSpectrumListSize();


  std::size_t spectrum_index = scan_number;
  qDebug();
  if(msrun_reader_sp.get()->hasScanNumbers())
    {
      qDebug() << "HAS SCAN NUMBERS";
      spectrum_index =
        msrun_reader_sp.get()->scanNumber2SpectrumIndex(scan_number);
    }
  qDebug() << " spectrum file="
           << msrun_reader_sp.get()->getMsRunId().get()->getFileName()
           << " index=" << spectrum_index;
  pappso::MassSpectrumCstSPtr spectrum_sp =
    msrun_reader_sp.get()->massSpectrumCstSPtr(spectrum_index);
  qDebug();
  return spectrum_sp;
}

void
IdentificationDataSource::addFastaFile(FastaFileSp file)
{
  _fastafile_list.push_back(file);
}
const std::vector<FastaFileSp> &
IdentificationDataSource::getFastaFileList() const
{
  return _fastafile_list;
}

bool
IdentificationDataSource::isValid(
  const PeptideEvidence *p_peptide_evidence,
  const AutomaticFilterParameters &automatic_filter_parameters) const
{

  if(automatic_filter_parameters.useFDR())
    {
      QVariant qvalue =
        p_peptide_evidence->getParam(PeptideEvidenceParam::pappso_qvalue);
      if(qvalue.isNull())
        {
          throw pappso::ExceptionNotFound(
            QObject::tr(
              "missing qvalues for identification engine %1, peptide %2")
              .arg(getIdentificationEngineName())
              .arg(p_peptide_evidence->getPeptideXtpSp().get()->getSequence()));
        }
      if(qvalue.toDouble() < automatic_filter_parameters.getFilterPeptideFDR())
        {
          return true;
        }
    }
  else
    {
      if(p_peptide_evidence->getEvalue() <=
         automatic_filter_parameters.getFilterPeptideEvalue())
        {
          return true;
        }
    }
  return false;
}
