/*******************************************************************************
**
** SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
** This file is part of the OfficeViewer project.
**
** Redistribution and use in source and binary forms,
** with or without modification, are permitted provided
** that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice,
**   this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
**   this list of conditions and the following disclaimer
**   in the documentation and/or other materials provided with the distribution.
** * Neither the name of the copyright holder nor the names of its contributors
**   may be used to endorse or promote products derived from this software
**   without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
** FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
** OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS;
** OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/



#include "converter.h"
#include <QDir>
#include <QThreadPool>
#include <QtConcurrent/QtConcurrent>
#include <QDebug>

#define LIBREOFFICE_PATH "/usr/share/ru.auroraos.OfficeViewer/lib/libreoffice/program"

Converter::Converter(QObject *parent)
    : QObject(parent)
    , m_office(nullptr)
    , m_document(nullptr)
    , m_state(State::Initilize)
{
    qRegisterMetaType<Converter::State>("Converter::State");
    m_office = lok::lok_cpp_init(LIBREOFFICE_PATH);
    if (!m_office) {
        setState(Converter::State::Failed);
        qWarning("Worker error: can't init the office instance");
    }
}

void Converter::convert(const QString &fileSourcePath, const QString &fileResultPath)
{
    if (m_state != State::Opened)
        return;

    auto worker = new ConverterWorker(m_office, fileSourcePath.toUtf8(), fileResultPath.toUtf8());
    connect(worker, &ConverterWorker::satateChanged, this, &Converter::setState);
    QThreadPool::globalInstance()->start(worker);
}

Converter::State Converter::state() const
{
    return m_state;
}

void Converter::setState(State newState)
{
    if (m_state == newState)
        return;
    m_state = newState;
    emit stateChanged();
}

ConverterWorker::ConverterWorker(lok::Office *office, const QByteArray &srcUrl, const QByteArray &dstUrl)
    : m_office(office)
    , m_srcUrl(srcUrl)
    , m_dstUrl(dstUrl)
{

}

void ConverterWorker::run()
{
    emit satateChanged(Converter::State::Opening);
    const int flags = LOK_FEATURE_DOCUMENT_PASSWORD | LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
                      | LOK_FEATURE_RANGE_HEADERS | LOK_FEATURE_VIEWID_IN_VISCURSOR_INVALIDATION_CALLBACK
                      | LOK_FEATURE_NO_TILED_ANNOTATIONS;
    m_office->setOptionalFeatures(flags);
    QString options;
    qDebug() << "Converting" << m_srcUrl << m_dstUrl;

    auto document = m_office->documentLoad(m_srcUrl.data(), options.toStdString().c_str());
    if (!document) {
        emit satateChanged(Converter::State::Failed);
        return;
    }

    emit satateChanged(Converter::State::Opened);
    emit satateChanged(Converter::State::Saving);

    bool status = document->saveAs(m_dstUrl.data());
    if (status) {
        emit satateChanged(Converter::State::Saved);
        qDebug() << "Converted" << m_dstUrl;
    } else {
        emit satateChanged(Converter::State::Failed);
        qDebug() << "Failed" << m_srcUrl << m_dstUrl;
    }
}

