#include "wallet_security_workflow.h"

#include <utility>

namespace dragonx {
namespace services {

void WalletSecurityWorkflow::reset()
{
    state_ = {};
}

void WalletSecurityWorkflow::start(std::chrono::steady_clock::time_point now)
{
    state_.phase = DecryptPhase::Working;
    state_.step = DecryptStep::Unlock;
    state_.status = stepStatus(DecryptStep::Unlock);
    state_.inProgress = true;
    state_.stepStarted = now;
    state_.overallStarted = now;
}

void WalletSecurityWorkflow::advanceTo(DecryptStep step, std::string status,
                                       std::chrono::steady_clock::time_point now)
{
    state_.phase = DecryptPhase::Working;
    state_.step = step;
    state_.status = std::move(status);
    state_.inProgress = true;
    state_.stepStarted = now;
}

void WalletSecurityWorkflow::failEntry(std::string status)
{
    state_.phase = DecryptPhase::PassphraseEntry;
    state_.step = DecryptStep::Unlock;
    state_.status = std::move(status);
    state_.inProgress = false;
}

void WalletSecurityWorkflow::fail(std::string status)
{
    state_.phase = DecryptPhase::Error;
    state_.status = std::move(status);
    state_.inProgress = false;
}

void WalletSecurityWorkflow::closeDialogForImport()
{
    state_.inProgress = false;
    state_.importActive = true;
}

void WalletSecurityWorkflow::finishImport()
{
    state_.importActive = false;
}

WalletSecurityWorkflow::WalletFilePlan WalletSecurityWorkflow::planWalletFiles(
    const std::string& dataDir,
    std::uint64_t timestampSeconds)
{
    WalletFilePlan plan;
    plan.dataDir = dataDir;
    plan.exportFile = WalletSecurityController::decryptExportFileName(timestampSeconds);
    plan.exportPath = dataDir + plan.exportFile;
    plan.walletPath = dataDir + "wallet.dat";
    plan.backupPath = dataDir + "wallet.dat.encrypted.bak";
    return plan;
}

const char* WalletSecurityWorkflow::stepStatus(DecryptStep step)
{
    switch (step) {
        case DecryptStep::Unlock: return "Unlocking wallet...";
        case DecryptStep::ExportKeys: return "Exporting wallet keys...";
        case DecryptStep::StopDaemon: return "Stopping daemon...";
        case DecryptStep::BackupWallet: return "Backing up encrypted wallet...";
        case DecryptStep::RestartDaemon: return "Restarting daemon...";
        case DecryptStep::ImportKeys: return "Importing wallet keys...";
    }
    return "";
}

const char* WalletSecurityWorkflow::stepLabel(DecryptStep step)
{
    switch (step) {
        case DecryptStep::Unlock: return "Unlocking wallet";
        case DecryptStep::ExportKeys: return "Exporting wallet keys";
        case DecryptStep::StopDaemon: return "Stopping daemon";
        case DecryptStep::BackupWallet: return "Backing up encrypted wallet";
        case DecryptStep::RestartDaemon: return "Restarting daemon";
        case DecryptStep::ImportKeys: return "Importing wallet keys";
    }
    return "";
}

WalletSecurityWorkflow::DecryptStep WalletSecurityWorkflow::stepFromIndex(int step)
{
    if (step <= 0) return DecryptStep::Unlock;
    if (step == 1) return DecryptStep::ExportKeys;
    if (step == 2) return DecryptStep::StopDaemon;
    if (step == 3) return DecryptStep::BackupWallet;
    if (step == 4) return DecryptStep::RestartDaemon;
    return DecryptStep::ImportKeys;
}

bool WalletSecurityWorkflow::stepIsComplete(DecryptStep current, DecryptStep candidate)
{
    return stepIndex(candidate) < stepIndex(current);
}

} // namespace services
} // namespace dragonx
