#include "NVMeDrive.hpp"

#include "NVMeError.hpp"
#include "NVMeSubsys.hpp"

#include <iostream>

namespace CommonErr = sdbusplus::xyz::openbmc_project::Common::Error;

NVMeDrive::NVMeDrive(boost::asio::io_context& io,
                     const std::shared_ptr<sdbusplus::asio::connection>& conn,
                     const std::string& path,
                     std::weak_ptr<NVMeSubsystem> subsys) :
    DriveBase(dynamic_cast<sdbusplus::bus_t&>(*conn), path.c_str()),
    DriveErase(dynamic_cast<sdbusplus::bus_t&>(*conn), path.c_str()),
    Asset(dynamic_cast<sdbusplus::bus_t&>(*conn), path.c_str()), path(path),
    sanitizeTimer(io), io(io), subsys(std::move(subsys))
{
    DriveBase::emit_added();
    DriveErase::emit_added();
    Asset::emit_added();
}

NVMeDrive::~NVMeDrive()
{
    sanitizeTimer.cancel();
    Asset::emit_removed();
    DriveErase::emit_removed();
    DriveBase::emit_removed();
}

// DriveErase.Erase method handler
void NVMeDrive::erase(EraseAction action)
{
    std::shared_ptr<NVMeSubsystem> s = subsys.lock();
    if (!s)
    {
        throw std::runtime_error("Sanitize called while shutting down");
    }

    NVMeSanitizeParams params(action);

    if (eraseInProgress())
    {
        // Already running
        if (params == sanitizeParams)
        {
            return;
        }
        // TODO: (b/375054188) Exception handling to be refactored
        // NOLINTNEXTLINE(cert-err09-cpp,cert-err60-cpp,cert-err61-cpp,misc-throw-by-value-catch-by-reference)
        throw *makeLibNVMeError(
            "sanitize already in progress with different parameters",
            std::make_shared<CommonErr::Unavailable>());
    }
    sanitizeParams = params;

    // Clear properties
    erasePercentage(0.0);
    errorName("");
    errorDescription("");
    // eraseInProgress() should always be set last.
    eraseInProgress(true);

    s->startSanitize(params, [self{shared_from_this()}](const nvme_ex_ptr& ex) {
        if (ex)
        {
            // Update properties with the submission failure
            self->erasePercentage(0.0);
            self->errorName(ex->name());
            self->errorDescription(ex->description());
            self->eraseInProgress(false);
        }
        else
        {
            // start the timer
            self->sanitizePoll();
        }
    });
}

void NVMeDrive::sanitizePoll()
{
    if (sanitizePollPending)
    {
        return;
    }
    sanitizePollPending = true;
    sanitizeTimer.expires_after(std::chrono::seconds(sanitizePollIntervalSecs));
    sanitizeTimer.async_wait(
        [weak{weak_from_this()}](boost::system::error_code ec) {
        if (ec == boost::asio::error::operation_aborted)
        {
            return;
        }

        auto self = weak.lock();
        if (!self)
        {
            return;
        }
        std::shared_ptr<NVMeSubsystem> s = self->subsys.lock();
        if (!s)
        {
            return;
        }

        self->sanitizePollPending = false;

        if (self->eraseInProgress())
        {
            s->sanitizeStatus([self](const nvme_ex_ptr& ex, bool inProgress,
                                     bool failed, bool completed,
                                     uint16_t sstat, uint16_t sprog,
                                     uint32_t scdw10) {
                (void)sstat;
                (void)sprog;
                (void)scdw10;
                if (ex)
                {
                    std::cerr << "Error returned reading sanitize log: " << ex
                              << '\n';
                }
                else
                {
                    if (completed)
                    {
                        self->erasePercentage(0.0);
                        self->eraseInProgress(false);
                    }
                    else if (failed)
                    {
                        self->erasePercentage(0.0);
                        self->eraseInProgress(false);
                        self->errorName(
                            CommonErr::DeviceOperationFailed::errName);
                        self->errorDescription("Sanitize operation failed");
                    }
                    else if (inProgress)
                    {
                        self->erasePercentage(100.0 * sprog / 0x10000);
                    }
                }

                if (self->eraseInProgress())
                {
                    self->sanitizePoll();
                }
            });
        }
    });
}

NVMeSanitizeParams::NVMeSanitizeParams(EraseAction sanact) :
    sanact(sanact), passes(1), pattern(0x0), patternInvert(false)
{}

enum nvme_sanitize_sanact NVMeSanitizeParams::nvmeAction() const
{
    switch (sanact)
    {
        case EraseAction::BlockErase:
            return NVME_SANITIZE_SANACT_START_BLOCK_ERASE;
        case EraseAction::CryptoErase:
            return NVME_SANITIZE_SANACT_START_CRYPTO_ERASE;
        case EraseAction::Overwrite:
            return NVME_SANITIZE_SANACT_START_OVERWRITE;
    }
    throw std::logic_error("unreachable");
}

bool NVMeSanitizeParams::matchesDword10(uint32_t dword10) const
{
    uint32_t ownDword10 = 0;

    // reconstruct the dword10 sent by libnvme
    ownDword10 |= (uint32_t)nvmeAction();
    ownDword10 |= (((uint32_t)patternInvert) << 8);
    ownDword10 |= (((uint32_t)passes & 0xf) << 4);

    return dword10 == ownDword10;
}
