/**
 * \file input/sage/sagefilereader.cpp
 * \date 11/10/2024
 * \author Olivier Langella
 * \brief read data files from Sage output containin multiple samples
 */

/*******************************************************************************
 * Copyright (c) 2024 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.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/>.
 *
 ******************************************************************************/

#include "sagefilereader.h"
#include "sagereader.h"
#include "pappsomspp/core/utils.h"
#include "pappsomspp/core/pappsoexception.h"
#include "pappsomspp/core/exception/exceptionnotrecognized.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QCborValue>

namespace pappso
{
namespace cbor
{
namespace psm
{

SageFileReader::SageFileReader(pappso::UiMonitorInterface *p_monitor,
                               pappso::cbor::CborStreamWriter *p_output,
                               const QFileInfo &sage_json_file)
  : m_sageJsonFile(sage_json_file)
{
  qDebug() << m_sageJsonFile.absoluteFilePath() << "'";
  try
    {

      mp_cborWriter = p_output;

      mp_cborWriter->startMap();
      mp_cborWriter->writeInformations(
        "sage_file_reader", Utils::getVersion(), "psm", "sage reader");

      QDir::setCurrent(sage_json_file.absolutePath());
      readJson();
      mp_cborWriter->append("parameter_map");
      mp_cborWriter->startMap();
      mp_cborWriter->append("sage");
      QCborValue::fromJsonValue(m_jsonData.object()).toCbor(*mp_cborWriter);
      mp_cborWriter->endMap();

      p_monitor->setStatus(
        QObject::tr("reading Sage json file %1").arg(sage_json_file.absoluteFilePath()));

      //  "decoy_tag": "rev_",
      //  "generate_decoys": true,
      // "target_fasta_files": ["zea_mays.fasta", "contaminant.fasta"],
      //"decoy_fasta_files": ["rev_zea_mays.fasta", "rev_contaminant.fasta"],

      mp_cborWriter->append("target_fasta_files");
      mp_cborWriter->writeArray(m_targetFastaFile);

      SageReader sage_reader(p_monitor, mp_cborWriter, *this, sage_json_file.absoluteFilePath());
      sage_reader.read();

      // mp_cborWriter->append("protein_map");
      //  sage_reader.getPsmProteinMap().

      mp_cborWriter->endMap();
    }
  catch(pappso::ExceptionNotRecognized &err)
    {
      throw err;
    }
  catch(pappso::PappsoException &other_err)
    {
      throw pappso::PappsoException(QObject::tr("Error reading Sage JSON file %1:\n%2")
                                      .arg(m_sageJsonFile.absoluteFilePath())
                                      .arg(other_err.qwhat()));
    }
}


SageFileReader::~SageFileReader()
{
}


void
SageFileReader::readJson()
{
  QFile mfile(m_sageJsonFile.absoluteFilePath());
  if(!mfile.open(QFile::ReadOnly))
    {
      throw pappso::ExceptionNotRecognized(
        QObject::tr("Unable to read Sage JSON file %1").arg(m_sageJsonFile.absoluteFilePath()));
    }
  QByteArray iContents = mfile.readAll();

  QJsonParseError parseError;
  m_jsonData = QJsonDocument::fromJson(iContents, &parseError);
  if(parseError.error != QJsonParseError::NoError)
    {
      throw pappso::ExceptionNotRecognized(QObject::tr("Error reading Sage JSON file %1 at %2:%3")
                                             .arg(m_sageJsonFile.absoluteFilePath())
                                             .arg(parseError.offset)
                                             .arg(parseError.errorString()));
    }

  QJsonValue mzml_value = m_jsonData.object().value("mzml_paths");

  if(mzml_value.isNull())
    {
      throw pappso::ExceptionNotRecognized(
        QObject::tr("Sage JSON file %1 does not contain mzml_paths")
          .arg(m_sageJsonFile.absoluteFilePath()));
    }
  for(const QJsonValue &value : m_jsonData.object().value("mzml_paths").toArray())
    {
      qDebug() << value.toString();

      // MsRunSp msrun_sp = p_project->getMsRunStore().getInstance(value.toString());
      m_mapFilePath2MsRunSp.insert(
        {QFileInfo(value.toString()).fileName(), QFileInfo(value.toString()).absoluteFilePath()});
    }


  m_sageVersion = m_jsonData.object().value("version").toString();


  QJsonObject sage_object = m_jsonData.object();


  QJsonObject database = sage_object.value("database").toObject();

  m_decoyTag      = database.value("decoy_tag").toString();
  m_generateDecoy = database.value("generate_decoy").toBool();
  m_targetFastaFile << database.value("fasta").toString();
}

const QJsonDocument &
SageFileReader::getJsonDocument() const
{
  return m_jsonData;
}


QString
SageFileReader::getMsRunSpWithFileName(const QString &msrun_filename) const
{
  auto it = m_mapFilePath2MsRunSp.find(msrun_filename);
  if(it != m_mapFilePath2MsRunSp.end())
    return it->second;


  throw pappso::PappsoException(QObject::tr("msrun filename %1 not found").arg(msrun_filename));
}

} // namespace psm
} // namespace cbor
} // namespace pappso
