/**
 * \file src/input/mzidentml/msrunsaxhandler.cpp
 * \date 23/02/2021
 * \author Olivier Langella
 * \brief parse mzIdentML result file to only get the msrun
 */


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

#include "msrunsaxhandler.h"


#include <pappsomspp/exception/exceptionnotfound.h>
#include "../../utils/utils.h"
#include "../datafilenotsupportedexception.h"


MsRunSaxHandler::MsRunSaxHandler()
{
  qDebug();
}
MsRunSaxHandler::~MsRunSaxHandler()
{
}

bool
MsRunSaxHandler::startElement(const QString &namespaceURI [[maybe_unused]],
                              const QString &localName [[maybe_unused]],
                              const QString &qName,
                              const QXmlAttributes &attributes)
{
  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  m_tagStack.push_back(qName);
  bool is_ok = true;

  try
    {
      // startElement_group
      if(m_tagStack.size() == 1)
        {
          if(qName != "MzIdentML")
            {
              throw DataFileNotSupportedException(
                QObject::tr("ERROR this file is not an MzIdentML file %1")
                  .arg(qName));
            }
        }
      else if(qName == "SpectraData")
        {
          is_ok = startElement_SpectraData(attributes);
        }
    }
  catch(const pappso::PappsoException &exception_pappso)
    {
      m_errorStr = QObject::tr(
                     "ERROR in MsRunSaxHandler::startElement tag "
                     "%1, PAPPSO exception:\n%2")
                     .arg(qName)
                     .arg(exception_pappso.qwhat());
      return false;
    }
  catch(const std::exception &exception_std)
    {
      m_errorStr = QObject::tr(
                     "ERROR in MsRunSaxHandler::startElement tag %1, std "
                     "exception:\n%2")
                     .arg(qName)
                     .arg(exception_std.what());
      return false;
    }
  if(!is_ok)
    {
      m_errorStr = QObject::tr(
                     "ERROR in MsRunSaxHandler::startElement tag "
                     "%1 :\n%2")
                     .arg(qName)
                     .arg(m_errorStr);
    }
  return is_ok;
}

bool
MsRunSaxHandler::endElement(const QString &namespaceURI [[maybe_unused]],
                            const QString &localName [[maybe_unused]],
                            const QString &qName)
{

  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  bool is_ok = true;
  // endElement_peptide_list
  try
    {
      if(qName == "SpectraData")
        {
          is_ok = endElement_SpectraData();
        }
      // end of detection_moulon
      // else if ((_tag_stack.size() > 1) &&
      //         (_tag_stack[_tag_stack.size() - 2] == "detection_moulon"))
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      m_errorStr = QObject::tr(
                     "ERROR in MsRunSaxHandler::endElement tag %1, "
                     "PAPPSO exception:\n%2")
                     .arg(qName)
                     .arg(exception_pappso.qwhat());
      return false;
    }
  catch(std::exception &exception_std)
    {
      m_errorStr = QObject::tr(
                     "ERROR in MsRunSaxHandler::endElement tag %1, std "
                     "exception:\n%2")
                     .arg(qName)
                     .arg(exception_std.what());
      return false;
    }

  m_tagStack.pop_back();

  if(!is_ok)
    {
      m_errorStr =
        QObject::tr("ERROR in MsRunSaxHandler::endElement tag %1 :\n%2")
          .arg(qName)
          .arg(m_errorStr);
    }
  return is_ok;
}


//<SpectraData
// location="/home/thierry/test/MS-GF+/20170308_test_dig_Liquide_01.mzXML"
// id="SID_1" name="20170308_test_dig_Liquide_01.mzXML">
//      <FileFormat>
//        <cvParam cvRef="PSI-MS" accession="MS:1000566" name="ISB mzXML
//        file"/>
//      </FileFormat>
//      <SpectrumIDFormat>
//        <cvParam cvRef="PSI-MS" accession="MS:1000776" name="scan number
//        only nativeID format"/>
//      </SpectrumIDFormat>
//    </SpectraData>

bool
MsRunSaxHandler::startElement_SpectraData(QXmlAttributes attributes)
{
  bool is_ok = true;

  if(m_spectraDataLocation.isEmpty())
    {
      m_spectraDataLocation = attributes.value("location");
    }
  else
    {

      m_errorStr = QObject::tr(
        "ERROR : more than one SpectraData input file defined in Inputs "
        "DataCollection for this mzIdentML file");
      is_ok = false;
    }

  return is_ok;
}


bool
MsRunSaxHandler::endElement_SpectraData()
{
  bool is_ok = true;
  return is_ok;
}

bool
MsRunSaxHandler::error(const QXmlParseException &exception)
{
  m_errorStr = QObject::tr(
                 "Parse error at line %1, column %2 :\n"
                 "%3")
                 .arg(exception.lineNumber())
                 .arg(exception.columnNumber())
                 .arg(exception.message());

  return false;
}


bool
MsRunSaxHandler::fatalError(const QXmlParseException &exception)
{
  m_errorStr = QObject::tr(
                 "Parse error at line %1, column %2 :\n"
                 "%3")
                 .arg(exception.lineNumber())
                 .arg(exception.columnNumber())
                 .arg(exception.message());
  return false;
}

QString
MsRunSaxHandler::errorString() const
{
  return m_errorStr;
}


bool
MsRunSaxHandler::endDocument()
{
  return true;
}

bool
MsRunSaxHandler::startDocument()
{
  return true;
}

const QString &
MsRunSaxHandler::getSpectraDataLocation() const
{
  return m_spectraDataLocation;
}
