/* -*- mode: c++; c-basic-offset:4 -*-
    commands/setinitialpincommand.cpp

    This file is part of Kleopatra, the KDE keymanager
    SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB

    SPDX-License-Identifier: GPL-2.0-or-later
*/

#include <config-kleopatra.h>

#include "setinitialpincommand.h"
#include "command_p.h"

#include <dialogs/setinitialpindialog.h>

#include <smartcard/readerstatus.h>

#include <KLocalizedString>


using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace Kleo::SmartCard;
using namespace GpgME;

class SetInitialPinCommand::Private : public Command::Private
{
    friend class ::Kleo::Commands::SetInitialPinCommand;
    SetInitialPinCommand *q_func() const
    {
        return static_cast<SetInitialPinCommand *>(q);
    }
public:
    explicit Private(SetInitialPinCommand *qq);
    ~Private();

private:
    void init()
    {

    }

    void ensureDialogCreated() const
    {
        if (dialog) {
            return;
        }

        SetInitialPinDialog *dlg = new SetInitialPinDialog;
        applyWindowID(dlg);
        dlg->setAttribute(Qt::WA_DeleteOnClose);
        dlg->setWindowTitle(i18nc("@title:window", "Set Initial Pin"));

        const std::vector<Card::PinState> pinStates = ReaderStatus::instance()->pinStates(0);

        dlg->setNksPinPresent(pinStates.size() >= 1 && pinStates[0] != Card::NullPin);
        dlg->setSigGPinPresent(pinStates.size() >= 3 && pinStates[2] != Card::NullPin);

        connect(dlg, SIGNAL(nksPinRequested()), q_func(), SLOT(slotNksPinRequested()));
        connect(dlg, SIGNAL(sigGPinRequested()), q_func(), SLOT(slotSigGPinRequested()));
        connect(dlg, SIGNAL(rejected()), q_func(), SLOT(slotDialogRejected()));
        connect(dlg, SIGNAL(accepted()), q_func(), SLOT(slotDialogAccepted()));

        dialog = dlg;
    }

    void ensureDialogVisible()
    {
        ensureDialogCreated();
        if (dialog->isVisible()) {
            dialog->raise();
        } else {
            dialog->show();
        }
    }

private:
    void slotNksPinRequested()
    {
        ReaderStatus::mutableInstance()
        ->startSimpleTransaction("SCD PASSWD --nullpin PW1.CH",
                                 dialog, "setNksPinSettingResult");
    }

    void slotSigGPinRequested()
    {
        ReaderStatus::mutableInstance()
        ->startSimpleTransaction("SCD PASSWD --nullpin PW1.CH.SIG",
                                 dialog, "setSigGPinSettingResult");
    }

    void slotDialogRejected()
    {
        if (dialog->isComplete()) {
            slotDialogAccepted();
        } else {
            canceled();
        }
    }
    void slotDialogAccepted()
    {
        ReaderStatus::mutableInstance()->updateStatus();
        finished();
    }

private:
    mutable QPointer<SetInitialPinDialog> dialog;
};

SetInitialPinCommand::Private *SetInitialPinCommand::d_func()
{
    return static_cast<Private *>(d.get());
}
const SetInitialPinCommand::Private *SetInitialPinCommand::d_func() const
{
    return static_cast<const Private *>(d.get());
}

#define q q_func()
#define d d_func()

SetInitialPinCommand::Private::Private(SetInitialPinCommand *qq)
    : Command::Private(qq, nullptr),
      dialog()
{

}

SetInitialPinCommand::Private::~Private() {}

SetInitialPinCommand::SetInitialPinCommand()
    : Command(new Private(this))
{
    d->init();
}

SetInitialPinCommand::~SetInitialPinCommand() {}

QDialog *SetInitialPinCommand::dialog() const
{
    d->ensureDialogCreated();
    return d->dialog;
}

void SetInitialPinCommand::doStart()
{
    d->ensureDialogVisible();
}

void SetInitialPinCommand::doCancel()
{
    if (d->dialog) {
        d->dialog->close();
    }
}

#undef q_func
#undef d_func

#include "moc_setinitialpincommand.cpp"
