// SPDX-FileCopyrightText: 2024 g10 Code GmbH
// SPDX-FileContributor: Carl Schwan <carl@carlschwan.eu>
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "filedecryptjob.h"

#include <QFile>
#include <QDebug>

#include <Libkleo/Formatting>
#include <QGpgME/DecryptJob>
#include <QGpgME/Protocol>

#include <gpgme++/context.h>
#include <gpgme++/decryptionresult.h>

#include "gpgmehelpers.h"

FileDecryptJob::FileDecryptJob(const QString &filePath, QObject *parent)
    : KJob(parent)
    , m_filePath(filePath)
{
}

QString FileDecryptJob::filePath() const
{
    return m_filePath;
}

QString FileDecryptJob::content() const
{
    return m_content;
}

void FileDecryptJob::start()
{
    QFile f(m_filePath);
    if (!f.open(QIODevice::ReadOnly)) {
        setError(AccessPermissionError);
        setErrorText(f.errorString());
        emitResult();
        return;
    }

    const auto data = f.readAll();
    QGpgME::Protocol *protocol = QGpgME::openpgp();
    m_job = protocol->decryptJob();
    connect(m_job,
            SIGNAL(result(GpgME::DecryptionResult, QByteArray, QString, GpgME::Error)),
            this,
            SLOT(slotDecryptedResult(GpgME::DecryptionResult, QByteArray, QString, GpgME::Error)));
    m_job->start(data);
}

void FileDecryptJob::slotDecryptedResult(const GpgME::DecryptionResult &result,
                                         const QByteArray &plainText,
                                         const QString &auditLogAsHtml,
                                         const GpgME::Error &auditLogError)
{
    Q_UNUSED(auditLogAsHtml);
    Q_UNUSED(auditLogError);

    auto context = QGpgME::Job::context(m_job);

    for (auto &recipient : result.recipients()) {
        GpgME::Error error;
        auto key = context->key(recipient.keyID(), error, false);
        if (!error) {
            m_recipients.append(QByteArray(key.keyID()));
        }
    }
    std::sort(m_recipients.begin(), m_recipients.end());

    if (isSuccess(result.error()) && result.numRecipients() > 0) {
        m_content = QString::fromUtf8(plainText);
    } else {
        setError(DecryptionError);
        setErrorText(Kleo::Formatting::errorAsString(result.error()));
    }

    emitResult();
}

QList<QByteArray> FileDecryptJob::recipients() const
{
    return m_recipients;
}
