
/*******************************************************************************
 * Copyright (c) 2016 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of i2MassChroQ.
 *
 *     i2MassChroQ 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.
 *
 *     i2MassChroQ 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 i2MassChroQ.  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/core/pappsoexception.h>
#include <pappsomspp/core/exception/exceptionnotfound.h>
#include <QFileInfo>
#include "../msrun.h"
#include "../peptideevidence.h"
#include <pappsomspp/core/msrun/private/timsmsrunreaderms2.h>
#include "../../utils/utils.h"

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

IdentificationDataSource::IdentificationDataSource(
  const IdentificationDataSource &other)
{
  msp_msRun       = other.msp_msRun;
  _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 msp_msRun.get()->getSampleName();
}

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

IdentificationEngine
IdentificationDataSource::getIdentificationEngine() const
{
  return m_identificationEngine;
}
const QString
IdentificationDataSource::getIdentificationEngineName() const
{

  // qDebug();
  return Utils::getIdentificationEngineName(m_identificationEngine);
}
const QString &
IdentificationDataSource::getIdentificationEngineVersion() const
{
  return _version;
}
void
IdentificationDataSource::setIdentificationEngineVersion(const QString &version)
{
  _version = version;
}
void
IdentificationDataSource::setIdentificationEngineParam(
  IdentificationEngineParam param, const QVariant &value)
{
  auto it = _params.insert(
    std::pair<IdentificationEngineParam, QVariant>(param, value));

  if(it.second == false)
    {
      it.first->second = 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)
{
  auto it = _param_stats.insert(
    std::pair<IdentificationEngineStatistics, QVariant>(param, value));
  if(it.second == false)
    {
      it.first->second = value;
    }
}
const QVariant
IdentificationDataSource::getIdentificationEngineStatistics(
  IdentificationEngineStatistics param) const
{
  try
    {
      return _param_stats.at(param);
    }
  catch(std::out_of_range &std_error)
    {
      return QVariant();
    }
}

void
IdentificationDataSource::addFastaFile(FastaFileSp file)
{
  // unicity check
  if(std::find_if(_fastafile_list.begin(),
                  _fastafile_list.end(),
                  [file](FastaFileSp &fasta_file_sp) {
                    return fasta_file_sp.get() == file.get();
                  }) == _fastafile_list.end())
    {

      _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.getAutomaticFilterType() ==
     AutomaticFilterType::fdr)
    {
      qDebug() << "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()));
        }
      qDebug() << qvalue.toDouble();
      if(qvalue.toDouble() < automatic_filter_parameters.getFilterPeptideFDR())
        {
          qDebug();
          return true;
        }
    }
  else if(automatic_filter_parameters.getAutomaticFilterType() ==
          AutomaticFilterType::evalue)
    {
      if(p_peptide_evidence->getEvalue() <=
         automatic_filter_parameters.getFilterPeptideEvalue())
        {
          // qDebug();
          return true;
        }
    }
  else if(automatic_filter_parameters.getAutomaticFilterType() ==
          AutomaticFilterType::svmprob)
    {
      auto svmprob =
        p_peptide_evidence->getParam(PeptideEvidenceParam::svmProb);
      if(svmprob.isNull())
        {

          throw pappso::PappsoException(
            QObject::tr("missing SVM probabilities, please run TIDD"));
        }
      if(svmprob.toDouble() >=
         automatic_filter_parameters.getSvmprobThreshold())
        {
          // qDebug();
          return true;
        }
    }
  // qDebug();
  return false;
}


void
IdentificationDataSource::fillProjectParameters(
  pappso::ProjectParameters &parameters [[maybe_unused]]) const
{
}
