/**
 * \file /output/mcqr/mcqrscprotein.cpp
 * \date 28/3/2018
 * \author Olivier Langella
 * \brief write protein sheet in MassChroqR format
 */

/*******************************************************************************
 * Copyright (c) 2018 Olivier Langella <olivier.langella@u-psud.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@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "mcqrscprotein.h"
#include <pappsomspp/core/pappsoexception.h>


McqRscProtein::McqRscProtein(CalcWriterInterface *p_writer,
                             const Project *p_project)
  : _p_project(p_project)
{
  _p_writer = p_writer;
}

void
McqRscProtein::writeSheet()
{
  _p_writer->writeSheet("protein_sc");

  std::vector<IdentificationGroup *> identification_list =
    _p_project->getIdentificationGroupList();
  if(identification_list.size() > 1)
    {
      throw pappso::PappsoException(
        QObject::tr("error : cannot write MassChroqR spectral count file in "
                    "individual mode"));
    }

  for(IdentificationGroup *p_ident : identification_list)
    {
      // writeHeaders(p_ident);
      writeIdentificationGroup(p_ident);
    }
}


void
McqRscProtein::writeHeaders(IdentificationGroup *p_ident [[maybe_unused]])
{

  // ProteinID, msrun, msrunfile, accession, description, q
  _p_writer->writeCell("peptide");
  _p_writer->writeCell("protein");
  _p_writer->writeCell("accession");
  _p_writer->writeCell("description");
  //_p_writer->writeCell(p_protein_match->countSampleScan(state, p_msrun));
}


void
McqRscProtein::writeIdentificationGroup(IdentificationGroup *p_ident)
{

  _ms_run_sp_list = p_ident->getMsRunSpList();
  writeHeaders(p_ident);
  for(const std::pair<const unsigned int, GroupingGroupSp> &group_pair :
      p_ident->getGroupStore().getGroupMap())
    {

      std::vector<const ProteinMatch *> protein_match_list =
        group_pair.second.get()->getProteinMatchList();

      std::sort(protein_match_list.begin(),
                protein_match_list.end(),
                [](const ProteinMatch *a, const ProteinMatch *b) {
                  return a->getGrpProteinSp().get()->getSubGroupNumber() <
                         b->getGrpProteinSp().get()->getSubGroupNumber();
                });

      for(auto &protein_match : protein_match_list)
        {
          writeOneProtein(group_pair.second.get(), protein_match);
        }
    }
  _p_writer->writeLine();
}


void
McqRscProtein::writeOneProtein(const GroupingGroup *p_group [[maybe_unused]],
                               const ProteinMatch *p_protein_match
                               [[maybe_unused]])
{
  try
    {

      qDebug() << "McqRscProtein::writeOneProtein begin";
      ValidationState validation_state = ValidationState::grouped;

      pappso::GrpProtein *p_grp_protein =
        p_protein_match->getGrpProteinSp().get();

      ProteinXtp *p_protein = p_protein_match->getProteinXtpSp().get();

      // for (MsRunSp & msrun_sp : _ms_run_sp_list) {
      std::set<QString> peptide_list;
      for(PeptideMatch &peptide_match :
          p_protein_match->getPeptideMatchList(validation_state))
        {
          peptide_list.insert(peptide_match.getPeptideEvidence()
                                ->getGrpPeptideSp()
                                .get()
                                ->getGroupingId());
        }

      for(const QString &peptide_str : peptide_list)
        {
          _p_writer->writeLine();

          _p_writer->writeCell(peptide_str);
          _p_writer->writeCell(p_grp_protein->getGroupingId());
          _p_writer->writeCell(p_protein->getAccession());
          _p_writer->writeCell(p_protein->getDescription());
        }
      qDebug() << "McqRscProtein::writeOneProtein end";
    }
  catch(pappso::PappsoException &error)
    {
      throw pappso::PappsoException(
        QObject::tr("Error writing protein %1 :\n%2")
          .arg(p_protein_match->getProteinXtpSp().get()->getAccession())
          .arg(error.qwhat()));
    }
}
