// 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 <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();
    auto job = protocol->decryptJob();
    connect(job, &QGpgME::DecryptJob::result, this, [this, job](auto &&result, QByteArray plainText, QString auditLog, auto &&logError) {
        Q_UNUSED(logError);
        Q_UNUSED(auditLog);

        auto context = QGpgME::Job::context(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();
    });
    job->start(data);
}

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