/*******************************************************************************
 * Copyright (c) 2020 Olivier Langella <olivier.langella@u-psud.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:
 *     Thomas Renne <thomas.renne@u-psud.fr> - initial API and
 *implementation
 ***************************/


#include "msrun.h"
#include "alignmentgroup.h"
#include <core/identification_sources/identificationdatasource.h>
#include "project.h"

MsRunAlignmentGroup::MsRunAlignmentGroup(Project *project, QString group_name)
{
  m_groupName = group_name;
  mp_project  = project;
}

MsRunAlignmentGroup::~MsRunAlignmentGroup()
{
}

QString
MsRunAlignmentGroup::getMsRunAlignmentGroupName()
{
  return m_groupName;
}

void
MsRunAlignmentGroup::setMsRunAlignmentGroupName(QString group_name)
{
  m_groupName = group_name;
}

std::list<MsRunSp>
MsRunAlignmentGroup::getMsRunsInAlignmentGroup() const
{
  return m_msrunAlignmentGroupList;
}

void
MsRunAlignmentGroup::addMsRunToMsRunAlignmentGroupList(MsRunSp new_msrun)
{
  m_msrunAlignmentGroupList.push_back(new_msrun);
}

void
MsRunAlignmentGroup::removeMsRunFromMsRunAlignmentGroupList(
  MsRunSp removed_msrun)
{
  if(removed_msrun.get()->getAlignmentGroup() != nullptr)
    {
      m_msrunAlignmentGroupList.remove(removed_msrun);
    }
}

MsRunSp
MsRunAlignmentGroup::getMsRunReference()
{
  return msp_msRunReference;
}

void
MsRunAlignmentGroup::setMsRunReference(MsRunSp reference)
{
  msp_msRunReference = reference;
}

void
MsRunAlignmentGroup::prepareMsrunRetentionTimesForAlignment() const
{
  qDebug() << "begin";

  for(auto &msrun_sp : getMsRunsInAlignmentGroup())
    {
      msrun_sp.get()->clearMsRunRetentionTime();
    }

  std::vector<IdentificationDataSourceSp> p_ident_data_sources;

  for(IdentificationDataSourceSp p_ident_data_source :
      mp_project->getIdentificationDataSourceStore()
        .getIdentificationDataSourceList())
    {
      if(std::find(m_msrunAlignmentGroupList.begin(),
                   m_msrunAlignmentGroupList.end(),
                   p_ident_data_source->getMsRunSp()) !=
         m_msrunAlignmentGroupList.end())
        {
          p_ident_data_sources.push_back(p_ident_data_source);
        }
    }

  bool is_ok = true;
  PeptideEvidenceStore empty_store;
  for(IdentificationDataSourceSp p_ident_data_source : p_ident_data_sources)
    {
      for(auto &peptide_evidence :
          p_ident_data_source->getPeptideEvidenceStore()
            .getPeptideEvidenceList())
        {
          if(peptide_evidence.get()->isValid())
            {
              MsRun *p_msrun = peptide_evidence.get()->getMsRunPtr();
              if(p_msrun->getMsRunRetentionTimePtr() == nullptr)
                {

                  p_msrun->buildMsRunRetentionTime(empty_store);
                  /*
                                    throw pappso::PappsoException(
                                      QObject::tr(
                                        "Error preparing msrun retention
                                        time
                     for %1 :\n " "p_msrun->getMsRunRetentionTimePtr() ==
                     nullptr") .arg(p_msrun->getXmlId()));
                                        */
                }
              p_msrun->getMsRunReaderSPtr()->acquireDevice();
              p_msrun->getMsRunRetentionTimePtr()->addPeptideAsSeamark(
                peptide_evidence.get()
                  ->getPeptideXtpSp()
                  .get()
                  ->getNativePeptideP(),
                p_msrun->getMsRunReaderSPtr().get()->scanNumber2SpectrumIndex(
                  peptide_evidence.get()->getScanNumber()));
              p_msrun->getMsRunReaderSPtr()->releaseDevice();
            }
        }
    }
  if(is_ok)
    {
      for(auto &msrun_sp : getMsRunsInAlignmentGroup())
        {
          msrun_sp->computeMsRunRetentionTime();
        }
      // find the best reference
    }
  else
    {
      for(auto &msrun_sp : getMsRunsInAlignmentGroup())
        {
          msrun_sp->clearMsRunRetentionTime();
        }
    }
  qDebug() << "end";
}
