/**
 * \file /input/xtandemparamsaxhandler.cpp
 * \date 19/9/2017
 * \author Olivier Langella
 * \brief XML handler for X!Tandem parameters file (presets)
 */

/*******************************************************************************
 * 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 "xtandemparamsaxhandler.h"
#include <pappsomspp/pappsoexception.h>
#include <QDebug>


XtandemParamSaxHandler::XtandemParamSaxHandler(
  TandemParameters *p_tandem_parameters)
{
  _p_tandem_parameters = p_tandem_parameters;

  //<note type="input" label="output, xsl path">tandem-style.xsl</note>
  _p_tandem_parameters->setParamLabelValue("output, xsl path",
                                           "tandem-style.xsl");
}
XtandemParamSaxHandler::~XtandemParamSaxHandler()
{
}

bool
XtandemParamSaxHandler::isTandemParameter() const
{
  return m_isTandemParameter;
}
bool
XtandemParamSaxHandler::startElement(const QString &namespaceURI
                                     [[maybe_unused]],
                                     const QString &localName [[maybe_unused]],
                                     const QString &qName,
                                     const QXmlAttributes &attributes)
{
  // qDebug()<< "XtandemParamSaxHandler::startElement begin" << namespaceURI <<
  // " " << localName << " " << qName ;
  _tag_stack.push_back(qName);
  bool is_ok = true;

  try
    {
      //<bioml label="example api document">
      if(_tag_stack.size() == 1)
        {
          if(qName != "bioml")
            {
              _errorStr = QObject::tr(
                            "ERROR in XtandemParamSaxHandler::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);
        }
      _current_text.clear();
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      _errorStr = QObject::tr(
                    "ERROR in XtandemParamSaxHandler::startElement "
                    "tag %1, PAPPSO exception:\n%2")
                    .arg(qName)
                    .arg(exception_pappso.qwhat());
      return false;
    }
  catch(std::exception &exception_std)
    {
      _errorStr = QObject::tr(
                    "ERROR in XtandemParamSaxHandler::startElement "
                    "tag %1, std exception:\n%2")
                    .arg(qName)
                    .arg(exception_std.what());
      return false;
    }
  return is_ok;
}

bool
XtandemParamSaxHandler::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();
        }
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      _errorStr = QObject::tr(
                    "ERROR in XtandemParamSaxHandler::endElement tag "
                    "%1, PAPPSO exception:\n%2")
                    .arg(qName)
                    .arg(exception_pappso.qwhat());
      return false;
    }
  catch(std::exception &exception_std)
    {
      _errorStr = QObject::tr(
                    "ERROR in XtandemParamSaxHandler::endElement tag "
                    "%1, std exception:\n%2")
                    .arg(qName)
                    .arg(exception_std.what());
      return false;
    }

  _current_text.clear();
  _tag_stack.pop_back();

  return is_ok;
}


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


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

QString
XtandemParamSaxHandler::errorString() const
{
  return _errorStr;
}


bool
XtandemParamSaxHandler::endDocument()
{

  return true;
}

bool
XtandemParamSaxHandler::startDocument()
{
  /*<?xml version="1.0" encoding="UTF-8"?>
  <bioml label="example api document">
  <note type="input" label="spectrum, parent monoisotopic mass error
  units">ppm</note> <note type="input" label="spectrum, parent monoisotopic mass
  error minus">10</note>
  */
  return true;
}

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

bool
XtandemParamSaxHandler::startElement_note(QXmlAttributes attributes)
{
  // qDebug() << "XtandemParamSaxHandler::startElement_note begin " <<
  // attributes.value("type");
  _current_label = "";

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

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

bool
XtandemParamSaxHandler::endElement_note()
{
  //    qDebug() << "XtandemParamSaxHandler::endElement_note begin " <<
  //    _current_label << " " << _current_text.simplified();
  if(!_current_label.isEmpty())
    {
      try
        {
          if(_current_label == "list path, default parameters")
            {
              m_presetFileInfo = QFileInfo(_current_text.simplified());
            }
          _p_tandem_parameters->setParamLabelValue(_current_label,
                                                   _current_text.simplified());
        }
      catch(pappso::PappsoException &exception)
        {
          _errorStr =
            QObject::tr("Error reading tandem input parameter \"%1\" :\n%2")
              .arg(_current_label)
              .arg(exception.qwhat());
          qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
                   << _errorStr;
          return false;
        }
    }
  return true;
}

QFileInfo
XtandemParamSaxHandler::getTandemPresetFileInfo() const
{
  return m_presetFileInfo;
}
