/**
 * \file pappsomspp/processing/xml/xmlstreamreaderinterface.cpp
 * \date 12/11/2021
 * \author Olivier Langella
 * \brief common interface to read all XML streams containing convenient
 * functions
 */

/*******************************************************************************
 * Copyright (c) 2021 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 "xmlstreamreaderinterface.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>

using namespace pappso;

XmlStreamReaderInterface::XmlStreamReaderInterface()
{
}

XmlStreamReaderInterface::~XmlStreamReaderInterface()
{
}

QString
pappso::XmlStreamReaderInterface::errorString() const
{
  if(m_qxmlStreamReader.errorString().isEmpty())
    return "";
  else
    {
      QString error = QObject::tr("ERROR at line %1 column %2\n%3")
                        .arg(m_qxmlStreamReader.lineNumber())
                        .arg(m_qxmlStreamReader.columnNumber())
                        .arg(m_qxmlStreamReader.errorString());
      return error;
    }
}

bool
pappso::XmlStreamReaderInterface::readFile(const QString &fileName)
{
  QFile file(fileName);
  if(!file.open(QFile::ReadOnly | QFile::Text))
    {
      m_qxmlStreamReader.raiseError(
        QObject::tr("Cannot read file %1 : %2")
          .arg(QFileInfo(fileName).absoluteFilePath())
          .arg(m_qxmlStreamReader.errorString()));
      return false;
    }

  if(read(&file))
    {
      file.close();
      return true;
    }
  else
    {
      file.close();
      m_qxmlStreamReader.raiseError(
        QObject::tr("Error reading file %1 : %2")
          .arg(QFileInfo(fileName).absoluteFilePath())
          .arg(m_qxmlStreamReader.errorString()));
      return false;
    }
}
bool
pappso::XmlStreamReaderInterface::read(QIODevice *device)
{

  m_qxmlStreamReader.setDevice(device);
  m_qxmlStreamReader.setNamespaceProcessing(true);
  readStream();

  return !m_qxmlStreamReader.error();
}

bool
pappso::XmlStreamReaderInterface::read(const QString &xml_content)
{
  m_qxmlStreamReader.clear();
  m_qxmlStreamReader.addData(xml_content);
  m_qxmlStreamReader.setNamespaceProcessing(true);
  readStream();

  return !m_qxmlStreamReader.error();
}
void
pappso::XmlStreamReaderInterface::cloneStartElement(
  QXmlStreamWriter &output) const
{
  output.writeStartElement(m_qxmlStreamReader.name().toString());

  for(auto declaration : m_qxmlStreamReader.namespaceDeclarations())
    {
      output.writeNamespace(declaration.namespaceUri().toString(),
                            declaration.prefix().toString());
    }
  output.writeAttributes(m_qxmlStreamReader.attributes());
}

void
pappso::XmlStreamReaderInterface::cloneElement(QXmlStreamWriter &output)
{
  qDebug() << " name=" << m_qxmlStreamReader.name();
  output.writeStartElement(m_qxmlStreamReader.namespaceUri().toString(),
                           m_qxmlStreamReader.name().toString());
  output.writeAttributes(m_qxmlStreamReader.attributes());

  qDebug() << m_qxmlStreamReader.name();
  while(m_qxmlStreamReader.readNext() && !m_qxmlStreamReader.isEndElement())
    {
      cloneNode(output);
      if(output.hasError())
        {
          qDebug();
          m_qxmlStreamReader.raiseError(QObject::tr("Error in output stream"));
        }
    }
  qDebug();
  output.writeEndElement();
}

void
pappso::XmlStreamReaderInterface::cloneNode(QXmlStreamWriter &output)
{
  qDebug();
  if(m_qxmlStreamReader.isCharacters())
    {
      qDebug() << "isCharacters " << m_qxmlStreamReader.text();
      if((m_qxmlStreamReader.text().toString() == "\n") ||
         (m_qxmlStreamReader.text().toString() == "\n\t"))
        {
          // xml cleaner
        }
      else
        {
          output.writeCharacters(
            m_qxmlStreamReader.text().toString().trimmed());
        }
    }
  else if(m_qxmlStreamReader.isEndElement())
    {
      qDebug() << "isEndElement";
      output.writeEndElement();
    }
  else if(m_qxmlStreamReader.isStartElement())
    {
      qDebug() << "isStartElement";
      cloneElement(output);
    }
  else
    {
    }
  qDebug();
}
