#include "NVMeError.hpp"

#include <libnvme-mi.h>

#include <xyz/openbmc_project/Common/Device/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

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

NVMeSdBusPlusError::NVMeSdBusPlusError(std::string_view desc) : desc(desc)
{
    init();
}

NVMeSdBusPlusError::NVMeSdBusPlusError(
    std::shared_ptr<sdbusplus::exception_t> specific) :
    specific(std::move(specific)) // NOLINT
{
    init();
}

NVMeSdBusPlusError::NVMeSdBusPlusError(
    std::string_view desc, std::shared_ptr<sdbusplus::exception_t> specific) :
    desc(desc), specific(std::move(specific)) // NOLINT
{
    init();
}

void NVMeSdBusPlusError::init()
{
    whatMsg = std::string(name()) + ": " + description(); // NOLINT
}

const char* NVMeSdBusPlusError::name() const noexcept
{
    if (specific)
    {
        return specific->name();
    }
    return CommonErr::InternalFailure().name();
}

const char* NVMeSdBusPlusError::description() const noexcept
{
    if (!desc.empty())
    {
        return desc.c_str();
    }
    if (specific)
    {
        return specific->description();
    }
    return "nvmesensor internal error";
}

const char* NVMeSdBusPlusError::what() const noexcept
{
    return whatMsg.c_str();
}

int NVMeSdBusPlusError::get_errno() const noexcept
{
    if (specific)
    {
        return specific->get_errno();
    }
    // arbitrary, sdbusplus method return ignores this errno
    return EIO;
}

void NVMeSdBusPlusError::print(std::ostream& o) const
{
    o << description();
}

/* Converts a subset of known status codes to dbus enums */
static void translateLibNVMe(int val, std::string& desc,
                             std::shared_ptr<sdbusplus::exception_t>& specific)
{
    uint16_t sc = nvme_status_code(val);
    uint16_t sct = nvme_status_code_type(val);

    switch (sct)
    {
        case NVME_SCT_GENERIC:
            switch (sc)
            {
                case NVME_SC_INVALID_FIELD:
                    specific = std::make_shared<CommonErr::InvalidArgument>();
                    break;

                case NVME_SC_CAP_EXCEEDED:
                    specific = std::make_shared<CommonErr::TooManyResources>();
                    break;

                case NVME_SC_SANITIZE_IN_PROGRESS:
                    specific = std::make_shared<CommonErr::Unavailable>();
                    break;

                default:
                    specific =
                        std::make_shared<CommonErr::DeviceOperationFailed>();
            }
            break;
        case NVME_SCT_CMD_SPECIFIC:
            switch (sc)
            {
                case NVME_SC_INVALID_FORMAT:
                    specific = std::make_shared<CommonErr::InvalidArgument>();
                    break;

                case NVME_SC_INSUFFICIENT_CAP:
                case NVME_SC_NS_INSUFFICIENT_CAP:
                case NVME_SC_NS_ID_UNAVAILABLE:
                case NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED:
                    specific = std::make_shared<CommonErr::TooManyResources>();
                    break;

                case NVME_SC_FW_NEEDS_SUBSYS_RESET:
                case NVME_SC_FW_NEEDS_RESET:
                    specific = std::make_shared<CommonErr::Unavailable>();
                    break;

                default:
                    specific =
                        std::make_shared<CommonErr::DeviceOperationFailed>();
            }
            break;
        default:
            specific = std::make_shared<CommonErr::DeviceOperationFailed>();
    }

    // always return the description from libnvme
    std::ostringstream s;
    s << "NVMe: " << nvme_status_to_string(val, false) << " (SCT " << sct
      << " SC 0x" << std::hex << sc << ")";
    desc = s.str();
}

static void
    translateLibNVMeMI(int val, std::string& desc,
                       std::shared_ptr<sdbusplus::exception_t>& specific)
{
    switch (val)
    {
        case NVME_MI_RESP_INVALID_PARAM:
            specific = std::make_shared<CommonErr::InvalidArgument>();
            break;

        case NVME_MI_RESP_SANITIZE_IN_PROGRESS:
            specific = std::make_shared<CommonErr::Unavailable>();
            break;

        // INVALID_CMD_SIZE is returned by some drives
        case NVME_MI_RESP_INVALID_OPCODE:
        case NVME_MI_RESP_INVALID_CMD_SIZE:
            specific = std::make_shared<CommonErr::UnsupportedRequest>();
            break;

        default:
            specific = std::make_shared<CommonErr::DeviceOperationFailed>();
    }

    // always return the description from libnvme
    std::ostringstream s;
    s << "NVMe MI: " << nvme_mi_status_to_string(val) << " (MI status 0x"
      << std::hex << val << ")";
    desc = s.str();
}

nvme_ex_ptr makeLibNVMeError(const std::error_code& err, int nvmeStatus,
                             const char* methodName)
{
    // TODO: possibly remove method_name argument
    (void)methodName;

    if (nvmeStatus < 0)
    {
        auto desc = std::string("libnvme error: ") + err.message();
        std::cerr << methodName << ":" << desc << '\n';
        return std::make_shared<NVMeSdBusPlusError>(desc);
    }
    if (nvmeStatus > 0)
    {
        int val = static_cast<int>(nvme_status_get_value(nvmeStatus));
        int ty = static_cast<int>(nvme_status_get_type(nvmeStatus));
        std::string desc;
        std::shared_ptr<sdbusplus::exception_t> specific;

        switch (ty)
        {
            case NVME_STATUS_TYPE_NVME:
                translateLibNVMe(val, desc, specific);
                break;
            case NVME_STATUS_TYPE_MI:
                translateLibNVMeMI(val, desc, specific);
                break;
            default:
                std::cerr << "Unknown libnvme error status " << nvmeStatus
                          << '\n';
                desc = "Unknown libnvme error";
        }
        std::cerr << methodName << ":" << desc << '\n';
        return std::make_shared<NVMeSdBusPlusError>(desc, specific);
    }
    // No Error
    return nullptr;
}

nvme_ex_ptr makeLibNVMeError(int nvmeErrno, int nvmeStatus,
                             const char* methodName)
{
    auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
    return makeLibNVMeError(err, nvmeStatus, methodName);
}

nvme_ex_ptr makeLibNVMeError(std::string_view msg)
{
    return std::make_shared<NVMeSdBusPlusError>(msg);
}

nvme_ex_ptr
    makeLibNVMeError(std::string_view desc,
                     const std::shared_ptr<sdbusplus::exception_t>& specific)
{
    return std::make_shared<NVMeSdBusPlusError>(desc, specific);
}

/* Throws an appropriate error type for the given status from libnvme,
 * or returns normally if nvme_status == 0 */
void checkLibNVMeError(const std::error_code& err, int nvmeStatus,
                       const char* methodName)
{
    auto e = makeLibNVMeError(err, nvmeStatus, methodName);
    if (e)
    {
        // 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 *e;
    }
}

std::ostream& operator<<(std::ostream& o, const nvme_ex_ptr& ex)
{
    if (ex)
    {
        ex->print(o);
    }
    else
    {
        o << "(null nvme_ex_ptr)";
    }
    return o;
}
