/**
 * \file src/ziptsvoutputstream.cpp
 * \date 27/6/2022
 * \author Olivier Langella
 * \brief write TSV files in a zip archive
 */

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

#include "ziptsvoutputstream.h"
#include "odsexception.h"
#include <QTextStream>
#include <QDebug>
#include <quacrc32.h>

ZipTsvOutputStream::ZipTsvOutputStream(const QString &zipfilename)
  : TsvDirectoryWriter()
{

  qDebug();
  mpa_fileZipArchive = new QFile(zipfilename);

  if(mpa_fileZipArchive->open(QIODevice::WriteOnly))
    {
    }
  else
    {
      throw OdsException(
        QString("unable to write into ZIP file %1")
          .arg(QFileInfo(*mpa_fileZipArchive).absoluteFilePath()));
    }

  qDebug();
  mpa_quaZip   = new QuaZip(mpa_fileZipArchive);
  bool open_ok = mpa_quaZip->open(QuaZip::mdCreate);

  if(open_ok == false)
    {
      throw OdsException(QObject::tr("error opening ZIP file."));
    }

  //_p_writer = new QXmlStreamWriter(&outFile);
  qDebug();
}


ZipTsvOutputStream::~ZipTsvOutputStream()
{
  qDebug();
  closeCurrentZipSheet();
  close();
  qDebug();
}

void
ZipTsvOutputStream::close()
{

  qDebug();

  TsvDirectoryWriter::close();
  closeCurrentZipSheet();
  if(mpa_quaZip != nullptr)
    {
      qDebug();
      mpa_quaZip->close();
      delete mpa_quaZip;
      mpa_quaZip = nullptr;
    }
  if(mpa_fileZipArchive != nullptr)
    {
      qDebug();
      mpa_fileZipArchive->close();
      delete mpa_fileZipArchive;
      mpa_fileZipArchive = nullptr;
    }
  qDebug();
}


void
ZipTsvOutputStream::closeCurrentZipSheet()
{

  qDebug();
  if(mpa_outFileInZip != nullptr)
    {
      qDebug();
      if(mpa_otxtstream != nullptr)
        {
          mpa_otxtstream->flush();
        }
      mpa_outFileInZip->close();
      qDebug();
      delete mpa_outFileInZip;
      mpa_outFileInZip = nullptr;
      qDebug();
    }
  qDebug();
}


void
ZipTsvOutputStream::writeSheet(const QString &sheetName)
{

  qDebug();
  closeCurrentZipSheet();
  if(mpa_outFileInZip == nullptr)
    {
      mpa_outFileInZip = new QuaZipFile(mpa_quaZip);
      QuaZipNewInfo info(QString("%1.tsv").arg(sheetName));
      info.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner |
                          QFileDevice::ReadGroup);

      if(mpa_outFileInZip->open(QIODevice::WriteOnly, info))
        {
          mpa_otxtstream = new QTextStream(mpa_outFileInZip);
        }
      else
        {
          throw OdsException(
            QString("unable to write into file %1 new sheet %2")
              .arg(QFileInfo(*mpa_fileZipArchive).absoluteFilePath())
              .arg(sheetName));
        }
    }
  else
    {
      throw OdsException(QString("mpa_outFileInZip == nullptr"));
    }
  initializeSheet();
  qDebug();
}
