/**
 * \file pappsomspp/processing/tandemwrapper/xtandempresetsaxhandler.cpp
 * \date 06/02/2020
 * \author Olivier Langella
 * \brief read tandem preset file to get centroid parameters and number of
 * threads
 */

/*******************************************************************************
 * Copyright (c) 2020 Olivier Langella <Olivier.Langella@u-psud.fr>.
 *
 * This file is part of PAPPSOms-tools.
 *
 *     PAPPSOms-tools 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.
 *
 *     PAPPSOms-tools 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 PAPPSOms-tools.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

#include "xtandempresetsaxhandler.h"
#include "../../pappsoexception.h"
#include "../../precision.h"

namespace pappso
{
XtandemPresetSaxHandler::XtandemPresetSaxHandler()
{
}

XtandemPresetSaxHandler::~XtandemPresetSaxHandler()
{
}


bool
XtandemPresetSaxHandler::startElement(const QString &namespaceURI
                                      [[maybe_unused]],
                                      const QString &localName [[maybe_unused]],
                                      const QString &qName,
                                      const QXmlAttributes &attributes)
{
  m_tagStack.push_back(qName);
  bool is_ok = true;

  try
    {
      m_currentText.clear();
      //<bioml label="example api document">
      if(m_tagStack.size() == 1)
        {
          if(qName != "bioml")
            {
              m_errorString =
                QObject::tr(
                  "ERROR in XtandemPresetSaxHandler::startElement "
                  "root tag %1 is not <bioml>")
                  .arg(qName);
              m_isTandemParameter = false;
              return false;
            }
          else
            {

              m_isTandemParameter = true;
            }
        }
      // startElement_group

      if(qName == "note")
        {
          is_ok = startElement_note(attributes);
        }
    }
  catch(const pappso::PappsoException &exception_pappso)
    {
      m_errorString = QObject::tr(
                        "ERROR in XtandemPresetSaxHandler::startElement "
                        "tag %1, PAPPSO exception:\n%2")
                        .arg(qName)
                        .arg(exception_pappso.qwhat());
      return false;
    }
  catch(const std::exception &exception_std)
    {
      m_errorString = QObject::tr(
                        "ERROR in XtandemPresetSaxHandler::startElement "
                        "tag %1, std exception:\n%2")
                        .arg(qName)
                        .arg(exception_std.what());
      return false;
    }
  return is_ok;
}

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

  bool is_ok = true;
  // endElement_peptide_list
  try
    {

      if(qName == "note")
        {
          is_ok = endElement_note();
        }
      else
        {
        }
    }
  catch(const pappso::PappsoException &exception_pappso)
    {
      m_errorString = QObject::tr(
                        "ERROR in XtandemPresetSaxHandler::endElement tag "
                        "%1, PAPPSO exception:\n%2")
                        .arg(qName)
                        .arg(exception_pappso.qwhat());
      return false;
    }
  catch(const std::exception &exception_std)
    {
      m_errorString = QObject::tr(
                        "ERROR in XtandemPresetSaxHandler::endElement tag "
                        "%1, std exception:\n%2")
                        .arg(qName)
                        .arg(exception_std.what());
      return false;
    }

  m_currentText.clear();
  m_tagStack.pop_back();

  return is_ok;
}

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

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

bool
XtandemPresetSaxHandler::characters(const QString &str)
{
  m_currentText += str;
  return true;
}


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


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

QString
XtandemPresetSaxHandler::errorString() const
{
  return m_errorString;
}


bool
XtandemPresetSaxHandler::startElement_note(QXmlAttributes attributes)
{
  // qDebug() << "XtandemParamSaxHandler::startElement_note begin " <<
  // <note type="input"
  // label="output,path">/gorgone/pappso/jouy/users/Celine/2019_Lumos/20191222_107_Juste_APD/metapappso_condor/test_run/20191222_18_EF1_third_step_test_condor_22janv.xml</note>

  m_currentLabel = "";

  if(attributes.value("type") == "input")
    {
      m_currentLabel = attributes.value("label");
    }

  //  qDebug() << "XtandemParamSaxHandler::startElement_note _current_label " <<
  //  _current_label;
  return true;
}

bool
XtandemPresetSaxHandler::endElement_note()
{
  //    qDebug() << "XtandemParamSaxHandler::endElement_note begin " <<
  //    _current_label << " " << _current_text.simplified();
  if(m_currentLabel == "spectrum, timstof MS2 filters")
    {
      // m_ms2filtersOptions = m_currentText;
    }
  else if(m_currentLabel == "spectrum, threads")
    {
      m_threads = m_currentText.toInt();
    }
  else if(m_currentLabel == "spectrum, fragment monoisotopic mass error units")
    {
      m_ms2precisionUnit = PrecisionUnit::dalton;
      if(m_currentText.trimmed().toLower() == "ppm")
        {
          m_ms2precisionUnit = PrecisionUnit::ppm;
        }
    }
  else if(m_currentLabel == "spectrum, fragment monoisotopic mass error")
    {
      m_ms2precisionValue = m_currentText.toDouble();
    }
  else
    {
    }
  return true;
}


int
XtandemPresetSaxHandler::getNumberOfThreads() const
{
  return m_threads;
}


const QString
XtandemPresetSaxHandler::getMs2FiltersOptions() const
{
  PrecisionPtr precision = PrecisionFactory::getPrecisionPtrInstance(
    m_ms2precisionUnit, m_ms2precisionValue);
  return QString("chargeDeconvolution|%1")
    .arg(precision->toString().replace(" ", ""));
}
} // namespace pappso
