/**
 * \file core/condor_process/condorqxmlsaxhandler.cpp
 * \date 15/9/2017
 * \author Olivier Langella
 * \brief parse condor_q XML
 */


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

CondorQxmlSaxHandler::CondorQxmlSaxHandler(CondorProcess *p_condor_process)
{
  m_isEmpty        = true;
  mp_condorProcess = p_condor_process;
}
CondorQxmlSaxHandler::~CondorQxmlSaxHandler()
{
}


bool
CondorQxmlSaxHandler::startElement(const QString &namespaceURI,
                                   const QString &localName,
                                   const QString &qName,
                                   const QXmlAttributes &attributes)
{
  qDebug() << "CondorQxmlSaxHandler::startElement begin" << namespaceURI << " "
           << localName << " " << qName;
  m_tagStack.push_back(qName);
  bool is_ok = true;

  try
    {
      // startElement_group

      if(qName == "c")
        {
          is_ok = startElement_c(attributes);
        }
      else if(qName == "a")
        {
          is_ok = startElement_a(attributes);
        }

      m_currentText.clear();
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      m_errorStr = QObject::tr(
                     "ERROR in CondorQxmlSaxHandler::startElement 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 CondorQxmlSaxHandler::startElement tag "
                     "%1, std exception:\n%2")
                     .arg(qName)
                     .arg(exception_std.what());
      return false;
    }
  return is_ok;
}

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

  bool is_ok = true;
  // endElement_peptide_list
  try
    {

      if(qName == "a")
        {
          is_ok = endElement_a();
        }
      else if(qName == "c")
        {
          is_ok = endElement_c();
        }
      else if(qName == "i")
        {
          is_ok = endElement_i();
        }
      else if(qName == "s")
        {
          is_ok = endElement_s();
        }
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      m_errorStr = QObject::tr(
                     "ERROR in CondorQxmlSaxHandler::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 CondorQxmlSaxHandler::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
CondorQxmlSaxHandler::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
CondorQxmlSaxHandler::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
CondorQxmlSaxHandler::errorString() const
{
  return m_errorStr;
}


bool
CondorQxmlSaxHandler::endDocument()
{

  std::size_t really_completed_jobs = 0;
  if(m_isEmpty)
    {
      really_completed_jobs = mp_condorProcess->getCondorJobSize();
    }
  else
    {
      int total_jobs = 0;
      for(std::int8_t i = 0; i < 10; i++)
        {
          total_jobs += m_countStatus[i];
        }

      int diff_jobs = mp_condorProcess->getCondorJobSize() - total_jobs;
      really_completed_jobs =
        m_countStatus[(std::int8_t)CondorJobStatus::Completed] + diff_jobs;
    }
  m_countStatus[(std::int8_t)CondorJobStatus::Completed] =
    really_completed_jobs;

  mp_condorProcess->setCondorJobStatus(m_countStatus);
  qDebug() << m_countStatus;
  return true;
}

bool
CondorQxmlSaxHandler::startDocument()
{
  for(std::int8_t i = 0; i < 10; i++)
    {
      m_countStatus[i] = 0;
    }
  m_isEmpty = true;
  return true;
}

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

bool
CondorQxmlSaxHandler::startElement_c(QXmlAttributes attributes [[maybe_unused]])
{

  // <c>
  // <a n="ProcId"><i>0</i></a>
  m_condorJobStatus       = CondorJobStatus::Unexpanded;
  m_currentProcId         = 0;
  m_isEmpty               = false;
  m_currentRemoteHost     = "";
  m_currentLastRemoteHost = "";
  return true;
}

bool
CondorQxmlSaxHandler::startElement_a(QXmlAttributes attributes)
{
  // logger.debug("startElementgroup begin");
  // <group label="performance parameters" type="parameters">
  m_inName = attributes.value("n");
  return true;
}

bool
CondorQxmlSaxHandler::endElement_a()
{
  m_inName = "";
  return true;
}

bool
CondorQxmlSaxHandler::endElement_i()
{
  if(m_inName == "ProcId")
    {
      m_currentProcId = m_currentText.toInt();
    }
  else if(m_inName == "JobStatus")
    {
      // <a n="JobStatus"><i>2</i></a>
      m_condorJobStatus = static_cast<CondorJobStatus>(m_currentText.toInt());
      // logger.debug(currentProcId);
    }
  return true;
}

bool
CondorQxmlSaxHandler::endElement_s()
{
  if(m_inName == "RemoteHost")
    {
      // <a n="RemoteHost"><s>slot1@proteus3</s></a>
      m_currentRemoteHost = m_currentText;
    }
  else if(m_inName == "LastRemoteHost")
    {
      // <a n="LastRemoteHost"><s>slot1@proteus4</s></a>
      m_currentLastRemoteHost = m_currentText;
    }
  return true;
}

bool
CondorQxmlSaxHandler::endElement_c()
{
  /*
   * 0 Unexpanded U 1 Idle I 2 Running R 3 Removed X 4 Completed C 5 Held
   * H 6 Submission_err E
   */
  m_countStatus[(std::int8_t)m_condorJobStatus] += 1;

  qDebug() << "currentRemoteHost:" << m_currentRemoteHost
           << " currentLastRemoteHost" << m_currentLastRemoteHost << " "
           << (std::int8_t)m_condorJobStatus;
  return true;
}

/*
package fr.inra.pappso.xtandempipeline.sax_parse;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import fr.inra.pappso.xtandempipeline.MsException.MSMSException;
import fr.inra.pappso.xtandempipeline.thread.XtandemCondorAnalysis;

public class HandlerHTCondorQueue extends SaxBaseHandler {

private static final Logger logger = Logger
    .getLogger(HandlerHTCondorQueue.class);
private Object inName;
private Integer currentProcId;
private Integer currentJobStatus;
private String currentRemoteHost;
private String currentLastRemoteHost;
private int junexpanded = 0;
private int jidle = 0;
private int jrunning = 0;
private int jremoved = 0;
private int jcompleted = 0;
private int jheld = 0;
private int jsubmission_error = 0;
private XtandemCondorAnalysis xtandemCondorAnalysis;
private boolean empty = true;

public HandlerHTCondorQueue(XtandemCondorAnalysis xtandemCondorAnalysis)
    throws MSMSException {
  super();
  this.xtandemCondorAnalysis = xtandemCondorAnalysis;
}

@Override
public void startDocument() throws SAXException {
  this.empty = true;
}


}
*/
