/*
    SPDX-FileCopyrightText: 2023 g10 Code GmbH
    SPDX-FileContributor: Sune Stolborg Vuorela <sune@vuorela.dk>

    SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "firsttimedialog.h"
#include "qdebug.h"

#include <QPixmap>

#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>

#include "gpgmehelpers.h"
#include "settings.h"
#include <KLocalizedString>
#include <QGpgME/KeyListJob>
#include <QProcess>
#include <QStandardPaths>
#include <gpgme++/keylistresult.h>

QList<UserInfo> DialogState::privateKeys() const
{
    auto job = protocol->keyListJob();
    std::vector<GpgME::Key> keys;
    auto result = job->exec(QStringList(), true, keys);
    if (!isSuccess(result.error())) {
        return {};
    }
    QList<UserInfo> users;
    for (const auto &key : keys) {
        UserInfo ui;
        ui.created = QDateTime::fromSecsSinceEpoch(key.subkey(0).creationTime());
        ui.key_id = fromGpgmeCharStar(key.keyID());
        ui.name = createCombinedNameString(key.userID(0));
        ui.validity = key.userID(0).validityAsString();
        ui.expiry = QDateTime::fromSecsSinceEpoch(key.subkey(0).expirationTime());
        ui.have_secret = key.hasSecret();
        users.append(ui);
    }
    return users;
}

FirstTimeDialog::FirstTimeDialog(QWidget *mainWindow)
    : m_mainWindow(mainWindow)
{
    setWindowTitle(i18n("GnuPG Password Manager setup"));
    setPage(Intro, new IntroPage(m_state));
    QTransform rotate;
    rotate.rotate(-90);

    setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/artwork/gnupg-logo-320x100tr.png")).transformed(rotate));
    setPixmap(QWizard::LogoPixmap, QPixmap(QLatin1String(":/artwork/64-gpgpass.png")));

    setStartId(Intro);
}

void FirstTimeDialog::doInitialSettings()
{
    QSettings s;
    s.setValue(QStringLiteral("setup"), true);
    if (Settings::getAutoclearSeconds() < 5)
        Settings::setAutoclearSeconds(10);
    if (Settings::getAutoclearPanelSeconds() < 5)
        Settings::setAutoclearPanelSeconds(10);
    Settings::setPassTemplate(QStringLiteral("login\nurl"));
}

void FirstTimeDialog::done(int i)
{
    if (i == QDialog::DialogCode::Accepted) {
        doInitialSettings();
        m_mainWindow->show();
    }
    QWizard::done(i);
}

bool FirstTimeDialog::wouldDoSomething() const
{
    return m_state.privateKeys().isEmpty();
}

int FirstTimeDialog::nextId() const
{
    switch (currentId()) {
    default:
        return -1;
    }
};

IntroPage::IntroPage(DialogState &s)
    : m_state(s)
    , m_kleoPath{QStandardPaths::findExecutable(QStringLiteral("kleopatra"))}
{
    {
        QVBoxLayout *lay = new QVBoxLayout();
        lay->addWidget(new QLabel(i18n("No private keys found. Please generate a key:")));
        lay->addWidget(new QLabel(i18n("in a terminal, run `gpg --gen-key` with relevant options")));
        if (!m_kleoPath.isEmpty()) {
            lay->addWidget(new QLabel(i18n("Or launch kleopatra to help create a key")));
            auto startKleo = new QPushButton(i18n("Launch kleopatra"), this);
            connect(startKleo, &QPushButton::clicked, this, [kleoPath = this->m_kleoPath]() {
                QProcess::startDetached(kleoPath, QStringList() << QStringLiteral("--gen-key"));
            });
            lay->addWidget(startKleo);
        }
        lay->addWidget(new QLabel(i18n("Please refresh once done")));
        auto refresh = new QPushButton(i18n("Refresh"));
        connect(refresh, &QPushButton::clicked, this, &IntroPage::refresh);
        lay->addWidget(refresh);

        m_noKeysContainer = new QWidget;
        m_noKeysContainer->setLayout(lay);
    }
    {
        QVBoxLayout *lay = new QVBoxLayout();
        lay->addWidget(new QLabel(i18n("Private keys found. Please close the dialog")));
        m_keysContainer = new QWidget;
        m_keysContainer->setLayout(lay);
    }
    QVBoxLayout *lay = new QVBoxLayout();

    setTitle(i18n("Welcome"));
    setSubTitle(i18n("Key generation"));

    lay->addWidget(new QLabel(i18n("Welcome to GnuPG Password manager")));
    lay->addWidget(m_noKeysContainer);
    lay->addWidget(m_keysContainer);
    m_keysContainer->hide();

    setLayout(lay);
    setFinalPage(true);
}
bool IntroPage::isComplete() const
{
    return !m_complete;
}

void IntroPage::refresh()
{
    bool pageComplete = m_state.privateKeys().isEmpty();
    if (pageComplete) {
        m_noKeysContainer->hide();
        m_keysContainer->show();
    } else {
        m_noKeysContainer->hide();
        m_keysContainer->show();
    }
    if (pageComplete) {
        m_complete = pageComplete;
        Q_EMIT completeChanged();
    }
}
