/**
 * \file /output/ods/samplesheet.cpp
 * \date 8/5/2017
 * \author Olivier Langella
 * \brief ODS sample sheet
 */

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

#include "samplesheet.h"

SampleSheet::SampleSheet(OdsExport *p_ods_export,
                         CalcWriterInterface *p_writer,
                         const Project *p_project)
  : _p_project(p_project)
{
  _p_writer     = p_writer;
  _p_ods_export = p_ods_export;
  p_writer->writeSheet("samples");

  OdsTableSettings table_settings;
  table_settings.setVerticalSplit(1);
  _p_writer->setCurrentOdsTableSettings(table_settings);

  writeHeaders();

  std::vector<IdentificationDataSourceSp> idrun_list =
    _p_project->getIdentificationDataSourceStore()
      .getIdentificationDataSourceList();

  for(IdentificationDataSourceSp idrun_sp : idrun_list)
    {
      writeIdentificationDataSource(idrun_sp.get());
    }
}

void
SampleSheet::writeHeaders()
{
  // MS sample name	X!tandem xml result file name	X!Tandem version
  // X!tandem xml model file name	total spectra used	total spectra assigned
  // assigned/used percent total unique assigned	database file names	MS/MS data
  // source file name	MS/MS data source file path MS level 1	MS level 2	TIC
  // mean in MS 1	TIC mean in MS 2	rt min	rt max


  _p_writer->writeLine();
  _p_writer->writeCell("sample ID");
  _p_writer->writeCell("sample");
  _p_writer->writeCell("MS run file");
  _p_writer->writeCell("Identification engine");
  _p_writer->writeCell("Identification engine version");
  _p_writer->writeCell("Identification result file");
  _p_writer->writeCell("Identification fasta files");
  _p_writer->writeCell("X!Tandem parameters");

  //   total_spectra_assigned=1, ///< total_spectra_assigned in one
  //   identification file (one sample)
  _p_writer->setCellAnnotation(
    "total spectra assigned in one identification file (one mzdata sample) "
    "given by the identification engine");
  _p_writer->writeCell("Total spectra assigned");
  //
  // total_spectra_used=2,///< total_spectra_used in one identification file
  // (one sample)
  _p_writer->setCellAnnotation(
    "total spectra used in one identification file (one mzdata sample) given "
    "by the identification engine");
  _p_writer->writeCell("Total spectra used");


  _p_writer->setCellAnnotation(
    "Percentage of spectra assignment (spectra assigned / spectra used");
  _p_writer->writeCell("Assignment percentage");

  // total_unique_assigned=5,///< total number unique peptide sequence assigned
  _p_writer->setCellAnnotation(
    "total unique peptide sequence assigned in one identification file (one "
    "mzdata sample) given by the identification engine");
  _p_writer->writeCell("Total unique assigned");


  if(_msrun_statistics)
    {
      _p_writer->setCellAnnotation(
        "total number of scans during the MS run (from mz file)");
      _p_writer->writeCell("Total scans");

      _p_writer->setCellAnnotation(
        "total number of MS level 1 during the MS run (from mz file)");
      _p_writer->writeCell("Total MS1");

      _p_writer->setCellAnnotation(
        "total number of MS level 2 during the MS run (from mz file)");
      _p_writer->writeCell("Total MS2");

      _p_writer->setCellAnnotation(
        "total number of MS level 3 during the MS run (from mz file)");
      _p_writer->writeCell("Total MS3");

      _p_writer->setCellAnnotation(
        "total ion current in MS level 1 spectra "
        "during the MS run (from mz file)");
      _p_writer->writeCell("TIC MS1");

      _p_writer->setCellAnnotation(
        "total ion current in MS level 2 spectra "
        "during the MS run (from mz file)");
      _p_writer->writeCell("TIC MS2");

      _p_writer->setCellAnnotation(
        "total ion current in MS level 3 spectra "
        "during the MS run (from mz file)");
      _p_writer->writeCell("TIC MS3");
    }

  /*
  total_peptide_used=3,///< total number of peptides generated and used in
  identification total_proteins_used=4,///< total number of proteins generated
  and used in identification

  */
}

void
SampleSheet::writeIdentificationDataSource(
  IdentificationDataSource *p_ident_data_source)
{
  _p_writer->writeLine();
  MsRunSp msrun_sp = p_ident_data_source->getMsRunSp();
  if(_msrun_statistics)
    {
      if(msrun_sp->findMsRunFile())
        {
          msrun_sp->checkMsRunStatistics();
        }
      msrun_sp->freeMsRunReaderSp();
    }

  _p_writer->writeCell(msrun_sp.get()->getXmlId());
  _p_writer->writeCell(msrun_sp.get()->getSampleName());
  _p_writer->writeCell(msrun_sp.get()->getFileName());
  _p_writer->writeCell(p_ident_data_source->getIdentificationEngineName());
  _p_writer->writeCell(p_ident_data_source->getIdentificationEngineVersion());
  _p_writer->writeCell(p_ident_data_source->getResourceName());

  QStringList fasta_files;
  for(FastaFileSp fasta_file : p_ident_data_source->getFastaFileList())
    {
      fasta_files << fasta_file.get()->getAbsoluteFilePath();
    }
  _p_writer->writeCell(fasta_files.join(" "));

  QVariant var_sample = p_ident_data_source->getIdentificationEngineParam(
    IdentificationEngineParam::tandem_param);
  if(var_sample.isNull())
    {
      _p_writer->writeEmptyCell();
    }
  else
    {
      _p_writer->writeCell(var_sample.toString());
    }
  var_sample = p_ident_data_source->getIdentificationEngineStatistics(
    IdentificationEngineStatistics::total_spectra_assigned);
  if(var_sample.isNull())
    {
      _p_writer->writeEmptyCell();
    }
  else
    {
      _p_writer->writeCell(var_sample.toInt());
    }
  var_sample = p_ident_data_source->getIdentificationEngineStatistics(
    IdentificationEngineStatistics::total_spectra_used);
  if(var_sample.isNull())
    {
      _p_writer->writeEmptyCell();
    }
  else
    {
      _p_writer->writeCell(var_sample.toInt());
    }

  if(!p_ident_data_source
        ->getIdentificationEngineStatistics(
          IdentificationEngineStatistics::total_spectra_assigned)
        .isNull() &&
     !p_ident_data_source
        ->getIdentificationEngineStatistics(
          IdentificationEngineStatistics::total_spectra_used)
        .isNull())
    {
      _p_writer->writeCellPercentage(
        p_ident_data_source
          ->getIdentificationEngineStatistics(
            IdentificationEngineStatistics::total_spectra_assigned)
          .toDouble() /
        p_ident_data_source
          ->getIdentificationEngineStatistics(
            IdentificationEngineStatistics::total_spectra_used)
          .toDouble());
    }
  else
    {
      _p_writer->writeEmptyCell();
    }


  var_sample = p_ident_data_source->getIdentificationEngineStatistics(
    IdentificationEngineStatistics::total_unique_assigned);
  if(var_sample.isNull())
    {
      _p_writer->writeEmptyCell();
    }
  else
    {
      _p_writer->writeCell(var_sample.toInt());
    }

  if(_msrun_statistics)
    {
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::total_spectra);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toInt());
        }
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::total_spectra_ms1);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toInt());
        }
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::total_spectra_ms2);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toInt());
        }
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::total_spectra_ms3);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toInt());
        }

      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::tic_spectra_ms1);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toDouble());
        }
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::tic_spectra_ms2);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toDouble());
        }
      var_sample =
        msrun_sp.get()->getMsRunStatistics(MsRunStatistics::tic_spectra_ms3);
      if(var_sample.isNull())
        {
          _p_writer->writeEmptyCell();
        }
      else
        {
          _p_writer->writeCell(var_sample.toDouble());
        }
    }
}
