#include "NVMeMi.hpp"

#include "NVMeError.hpp"
#include "NVMeUtil.hpp"

#include <endian.h>

#include <boost/endian.hpp>

#include <cassert>
#include <cerrno>
#include <fstream>
#include <iostream>
#include <stdexcept>

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

// libnvme-mi root service
nvme_root_t NVMeMi::nvmeRoot = nvme_mi_create_root(stderr, DEFAULT_LOGLEVEL);

constexpr size_t maxNVMeMILength = 4096;
constexpr int tcgDefaultTimeoutMS = 20 * 1000;
constexpr int namespaceDefaultTimeoutMS = 20 * 1000;
constexpr int sanitizeDefaultTimeoutMS = 20 * 1000;
constexpr int downloadDefaultTimeoutMS = 10 * 1000;
constexpr int initCmdTimeoutMS = 1000;

NVMeMi::NVMeMi(boost::asio::io_context& io,
               const std::shared_ptr<sdbusplus::asio::connection>& conn,
               const std::shared_ptr<const MctpDevice>& device,
               const std::shared_ptr<NVMeMiWorker>& worker,
               PowerState readState) :
    io(io), device(device), readState(readState), mctpStatus(Status::Reset),
    mtu(64), nvmeEP(nullptr), restart(false), worker(worker)
{
    // set update the worker thread
    if (nvmeRoot == nullptr)
    {
        throw std::runtime_error("invalid NVMe root");
    }

    // setup the power state
    if (readState == PowerState::on || readState == PowerState::biosPost ||
        readState == PowerState::chassisOn)
    {
        // life time of the callback is binding to the NVMeMi instance, so only
        // this capture is required.
        powerCallback = setupPowerMatchCallback(conn, [this](PowerState, bool) {
            if (!::readingStateGood(this->readState))
            {
                recover();
            }
        });
    }
}

void NVMeMi::epReset()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return;
        case Status::Initiated:
            if (optimizeTimer)
            {
                std::cerr << "[" << endpoint->describe() << "]"
                          << "Cancel the optimization Timer for the endpoint"
                          << '\n';
                optimizeTimer->cancel();
            }
            [[fallthrough]];
        case Status::Connected:
            if (nvmeEP == nullptr)
            {
                throw std::logic_error(
                    "nvmeEP was unpopulated in Status::Initiated state");
            }
            mctpStatus = Status::Terminating;
            std::cerr << "[" << endpoint->describe() << "]"
                      << "start MCTP closure" << '\n';
            // Immediately reset endpoint so that we can capture the parameter
            // from a subsequent invocation of start() while in
            // Status::Terminating
            endpoint.reset();
            // Invoke nvme_mi_close() via a lambda that we schedule via
            // flushOperations(). Using flushOperations() ensures that any
            // outstanding tasks are executed before nvme_mi_close() is invoked,
            // invalidating their controller reference.
            flushOperations([self{shared_from_this()}]() {
                nvme_mi_close(self->nvmeEP);
                self->mtu = 64;
                self->nvmeEP = nullptr;
                self->mctpStatus = Status::Reset;
                std::cerr << "[" << self->device->describe() << "] "
                          << "end MCTP closure" << '\n';
                if (self->restart)
                {
                    // If restart is true then we've captured the updated
                    // endpoint. We pass it to start() to recreate the
                    // connection.
                    self->restart = false;
                    self->start(self->endpoint);
                }
            });
            return;
        case Status::Terminating:
            return;
    }
    throw std::logic_error("Unreachable");
}

bool NVMeMi::epConnect(int lnid, uint8_t leid)
{
    switch (mctpStatus)
    {
        case Status::Reset:
            if (nvmeEP != nullptr)
            {
                throw std::logic_error(
                    "nvmeEP populated in Status::Reset state");
            }
            nvmeEP = nvme_mi_open_mctp(nvmeRoot, lnid, leid);
            if (nvmeEP != nullptr)
            {
                mctpStatus = Status::Initiated;
                return true;
            }
            return false;
        case Status::Initiated:
        case Status::Connected:
            return true;
        case Status::Terminating:
            // This isn't an error so much as we're just not ready yet
            return false;
    }
    throw std::logic_error("Unreachable");
}

void NVMeMi::epOptimize()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            throw std::logic_error("optimize called from Status::Reset");
        case Status::Initiated:
            /* Continue with optimization below */
            break;
        case Status::Connected:
            /* Already optimized */
            return;
        case Status::Terminating:
            throw std::logic_error("optimize called from Status::Terminating");
    }

    // If the device is behind a bridge (so not directly I2C accessible), we
    // skip MTU and SMBus frequency configuration.
    if (!endpoint->isI2cAccessible())
    {
        mctpStatus = Status::Connected;
        return;
    }

    optimizeTimer = std::make_shared<boost::asio::steady_timer>(
        io, std::chrono::milliseconds(500));
    optimizeTimer->async_wait([this](boost::system::error_code ec) {
        if (ec)
        {
            std::cerr << "Endpoint optimize timer error " << ec << '\n';
            return;
        }
        miSetMCTPConfiguration(
            [self{shared_from_this()}](const std::error_code& ec) {
            self->optimizeTimer = nullptr;
            if (ec)
            {
                std::cerr << "[" << self->device->describe() << "]"
                          << "Failed setting up MTU for the MCTP endpoint."
                          << '\n';
                self->recover();
                return;
            }
            self->configureLocalRouteMtu([self](const std::error_code& ec) {
                if (ec)
                {
                    self->recover();
                    return;
                }
                self->mctpStatus = Status::Connected;
            });
        });
    });
}

void NVMeMi::recover()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return;
        case Status::Initiated:
        case Status::Connected:
            endpoint->recover();
            return;
        case Status::Terminating:
            return;
    }
    throw std::logic_error("Unreachable");
}

void NVMeMi::start(const std::shared_ptr<MctpEndpoint>& ep)
{
    if (mctpStatus == Status::Terminating)
    {
        endpoint = ep;
        this->restart = true;
        return;
    }

    if (mctpStatus == Status::Reset)
    {
        endpoint = ep;
        // open mctp endpoint
        if (!epConnect(endpoint->network(), endpoint->eid()))
        {
            epReset();
            std::cerr << "[" << ep->describe() << "]"
                      << "can't open MCTP endpoint " << '\n';
            return;
        }
    }

    if (mctpStatus == Status::Initiated)
    {
        epOptimize();
    }
}

void NVMeMi::stop()
{
    restart = false;
    epReset();
}

std::optional<std::error_code> NVMeMi::isEndpointDegraded() const
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return std::make_error_code(std::errc::no_such_device);
        case Status::Initiated:
            return std::make_error_code(std::errc::not_connected);
        case Status::Connected:
            return std::nullopt;
        case Status::Terminating:
            return std::make_error_code(std::errc::not_connected);
    }
    throw std::logic_error("Unreachable");
}

NVMeMiWorker::NVMeMiWorker()
{ // start worker thread
    thread = std::thread([&io = workerIO, &stop = workerStop, &mtx = workerMtx,
                          &cv = workerCv, &isNotified = workerIsNotified]() {
        // With BOOST_ASIO_DISABLE_THREADS, boost::asio::executor_work_guard
        // issues null_event across the thread, which caused invalid invokation.
        // We implement a simple invoke machenism based std::condition_variable.
        while (true)
        {
            io.run();
            io.restart();
            {
                std::unique_lock<std::mutex> lock(mtx);
                cv.wait(lock, [&]() { return isNotified; });
                isNotified = false;

                if (stop)
                {
                    // exhaust all tasks and exit
                    io.run();
                    break;
                }
            }
        }
    });
}

NVMeMiWorker::~NVMeMiWorker()
{
    // close worker
    workerStop = true;
    {
        std::unique_lock<std::mutex> lock(workerMtx);
        workerIsNotified = true;
        workerCv.notify_all();
    }
    thread.join();
}

NVMeMi::~NVMeMi()
{
    // If we're being destructed the only thing left to do is to clean up the
    // endpoint connection. We're in the destructor because the last shared
    // reference has been dropped, which means it must be the case that no
    // worker jobs remain queued that reference the instance.
    //
    // We can't call epReset() here via stop() as was originally the case.
    // epReset() prepares the NVMeMi instance for a subsequent epConnect() using
    // shared_from_this(), which will yield a std::bad_weak_ptr now that we're
    // in the destructor. Moreover, a subsequent epConnect() is not possible
    // beyond this point.
    if (nvmeEP != nullptr)
    {
        nvme_mi_close(nvmeEP);
    }
}

void NVMeMiWorker::post(std::function<void(void)>&& func)
{
    if (!workerStop)
    {
        std::unique_lock<std::mutex> lock(workerMtx);
        if (!workerStop)
        {
            workerIsNotified = true;
            workerIO.post(std::move(func));
            workerCv.notify_all();
            return;
        }
    }
    throw std::runtime_error("NVMeMi has been stopped");
}

void NVMeMi::post(std::function<void(void)>&& func)
{
    worker->post([func{std::move(func)}]() { func(); });
}

// Calls .post(), catching runtime_error and returning an error code on failure.
std::error_code NVMeMi::tryPost(std::function<void(void)>&& func)
{
    try
    {
        post([self{shared_from_this()}, func{std::move(func)}]() { func(); });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << device->describe() << "]" << e.what() << '\n';
        return std::make_error_code(std::errc::no_such_device);
    }
    return {};
}

void NVMeMi::miConfigureSMBusFrequency(
    uint8_t portId, uint8_t /*maxSupportedFreq*/,
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        std::cerr << "[" << device->describe() << "]"
                  << "nvme endpoint is invalid" << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([portId, ep{endpoint}, self{shared_from_this()},
              cb{std::move(cb)}]() mutable {
            enum nvme_mi_config_smbus_freq smbusFreq = {};
            auto rc = nvme_mi_mi_config_get_smbus_freq(self->nvmeEP, portId,
                                                       &smbusFreq);
            if (rc != 0)
            {
                std::cerr << "[" << ep->describe()
                          << "] failed to get the SMBus frequency " << '\n';
            }
            else if (smbusFreq == NVME_MI_CONFIG_SMBUS_FREQ_100kHz)
            {
                std::cerr << "[" << ep->describe()
                          << "] Setting the SMBus frequency to 400kHz\n";
                rc = nvme_mi_mi_config_set_smbus_freq(
                    self->nvmeEP, portId, NVME_MI_CONFIG_SMBUS_FREQ_400kHz);
                if (rc != 0)
                {
                    std::cerr << "[" << ep->describe()
                              << "] failed to set the SMBus frequency\n";
                }
            }
            if (rc != 0)
            {
                self->io.post([cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }
            self->io.post([cb{std::move(cb)}]() { cb({}); });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << device->describe() << "]" << e.what() << '\n';
        return;
    }
}

void NVMeMi::miConfigureRemoteMCTP(
    uint8_t port, uint16_t mtu, uint8_t maxSupportedFreq,
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        std::cerr << "[" << device->describe() << "] "
                  << "nvme endpoint is invalid" << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([port, mtu, maxSupportedFreq, self{shared_from_this()},
              cb{std::move(cb)}]() mutable {
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, initCmdTimeoutMS);
            auto rc = nvme_mi_mi_config_set_mctp_mtu(self->nvmeEP, port, mtu);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

            if (rc != 0)
            {
                std::cerr << "[" << self->device->describe() << "]"
                          << " failed to set remote MCTP MTU for port :"
                          << unsigned(port) << '\n';
                self->io.post([cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }
            self->mtu = mtu;
            if (maxSupportedFreq >= 2)
            {
                self->io.post([self, port, maxSupportedFreq,
                               cb{std::move(cb)}]() mutable {
                    self->miConfigureSMBusFrequency(port, maxSupportedFreq,
                                                    std::move(cb));
                });
                return;
            }
            self->io.post([cb{std::move(cb)}]() { cb({}); });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << device->describe() << "] " << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
}

void NVMeMi::miSetMCTPConfiguration(
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        std::cerr << "[" << device->describe() << "] "
                  << "nvme endpoint is invalid" << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([cb{std::move(cb)}, self{shared_from_this()}]() mutable {
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, initCmdTimeoutMS);
            struct nvme_mi_read_nvm_ss_info ssInfo = {};
            auto rc = nvme_mi_mi_read_mi_data_subsys(self->nvmeEP, &ssInfo);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
            if (rc != 0)
            {
                std::cerr << "[" << self->device->describe() << "] "
                          << "Failed reading subsystem info failing " << '\n';
                self->io.post([cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }

            for (uint8_t portId = 0; portId <= ssInfo.nump; portId++)
            {
                struct nvme_mi_read_port_info portInfo = {};
                auto rc = nvme_mi_mi_read_mi_data_port(self->nvmeEP, portId,
                                                       &portInfo);
                if (rc != 0)
                {
                    /* PCIe port might not be ready right after AC/DC cycle. */
                    std::cerr << "[" << self->device->describe()
                              << "] failed reading port info for port_id: "
                              << unsigned(portId) << '\n';
                }
                else if (portInfo.portt == 0x2) // SMBus ports = 0x2
                {
                    uint16_t supportedMtu = portInfo.mmctptus;
                    uint8_t supportedFreq = portInfo.smb.mme_freq; // NOLINT
                    self->io.post([self, portId, supportedMtu, supportedFreq,
                                   cb{std::move(cb)}]() mutable {
                        self->miConfigureRemoteMCTP(
                            portId, supportedMtu, supportedFreq, std::move(cb));
                    });
                    return;
                }
            }
            // Didn't find the SMbus port
            self->io.post([cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device));
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << device->describe() << "]" << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
}

void NVMeMi::configureLocalRouteMtu(
    std::function<void(const std::error_code& ec)>&& completed, int retries)
{
    const uint32_t mctpMtu = mtu + 4;
    std::function<void(const std::error_code& ec)> retry =
        [this, cb{std::move(completed)},
         retries](const std::error_code& ec) mutable {
        if (!endpoint)
        {
            std::cerr << "[" << device->describe() << "] "
                      << "failed to set MCTP path MTU: Status::Terminating"
                      << '\n';
            cb(ec);
            return;
        }

        if (!ec)
        {
            std::cout << "[" << endpoint->describe() << "] "
                      << "Finished MCTP initialization. MTU: " << mtu << '\n';
            cb(ec);
            return;
        }

        retries--;
        if (retries == 0)
        {
            std::cerr << "[" << endpoint->describe() << "] "
                      << "failed to set MCTP path MTU: " << ec.message()
                      << '\n';
            cb(ec);
            return;
        }

        std::cerr << "[" << endpoint->describe() << "] "
                  << "retry to set MCTP path MTU" << '\n';
        configureLocalRouteMtu(std::move(cb), retries);
    };
    endpoint->setMtu(mctpMtu, std::move(retry));
}

void NVMeMi::miSubsystemHealthStatusPoll(
    std::function<void(const std::error_code&, nvme_mi_nvm_ss_health_status*)>&&
        cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';

        io.post([cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nullptr);
        });
        return;
    }

    try
    {
        post([self{shared_from_this()}, ep{endpoint}, cb{std::move(cb)}]() {
            nvme_mi_nvm_ss_health_status ssHealth = {};
            auto rc = nvme_mi_mi_subsystem_health_status_poll(self->nvmeEP,
                                                              true, &ssHealth);
            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << " fail to subsystem_health_status_poll: "
                          << std::strerror(errno) << '\n';
                self->io.post([cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       nullptr);
                });
                return;
            }
            if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                std::cerr << "[" << ep->describe() << "]"
                          << " fail to subsystem_health_status_poll: " << errMsg
                          << '\n';
                self->io.post([cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), nullptr);
                });
                return;
            }

            self->io.post(
                [cb{cb}, ssHealth{ssHealth}]() mutable { cb({}, &ssHealth); });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << device->describe() << "]" << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

void NVMeMi::miScanCtrl(std::function<void(const std::error_code&,
                                           const std::vector<nvme_mi_ctrl_t>&)>
                            cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';

        io.post(
            [cb{std::move(cb)}, errc{degraded.value()}]() { cb(errc, {}); });
        return;
    }

    try
    {
        post([self{shared_from_this()}, ep{endpoint}, cb{std::move(cb)}]() {
            int rc = nvme_mi_scan_ep(self->nvmeEP, true);
            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to scan controllers: "
                          << std::strerror(errno) << '\n';
                self->io.post([cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {});
                });
                return;
            }
            if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to scan controllers: " << errMsg << '\n';
                self->io.post([cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), {});
                });
                return;
            }

            std::vector<nvme_mi_ctrl_t> list;
            nvme_mi_ctrl_t c = {};
            nvme_mi_for_each_ctrl(self->nvmeEP, c)
            {
                list.push_back(c);
            }
            self->io.post(
                [cb{cb}, list{std::move(list)}]() mutable { cb({}, list); });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << endpoint->describe() << "]" << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

bool NVMeMi::flushOperations(std::function<void()>&& cb)
{
    try
    {
        post([self{shared_from_this()}, cb{std::move(cb)}]() {
            self->io.post(cb);
        });

        return true;
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "Runtime error: " << e.what() << '\n';
        return false;
    }
}

void NVMeMi::adminIdentify(
    nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid, uint16_t cntid,
    std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';
        io.post([cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(makeLibNVMeError("nvme endpoint is degraded"), {});
        });
        return;
    }
    try
    {
        post([ctrl, cns, nsid, cntid, self{shared_from_this()}, ep{endpoint},
              cb{std::move(cb)}]() {
            int rc = 0;
            std::vector<uint8_t> data;
            switch (cns)
            {
                case NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST:
                {
                    data.resize(sizeof(nvme_secondary_ctrl_list));
                    nvme_identify_args args{};
                    memset(&args, 0, sizeof(args));
                    args.result = nullptr;
                    args.data = data.data();
                    args.args_size = sizeof(args);
                    args.cns = cns;
                    args.csi = NVME_CSI_NVM;
                    args.nsid = nsid;
                    args.cntid = cntid;
                    args.cns_specific_id = NVME_CNSSPECID_NONE;
                    args.uuidx = NVME_UUID_NONE,

                    rc = nvme_mi_admin_identify_partial(ctrl, &args, 0,
                                                        data.size());

                    break;
                }

                default:
                {
                    data.resize(NVME_IDENTIFY_DATA_SIZE);
                    nvme_identify_args args{};
                    memset(&args, 0, sizeof(args));
                    args.result = nullptr;
                    args.data = data.data();
                    args.args_size = sizeof(args);
                    args.cns = cns;
                    args.csi = NVME_CSI_NVM;
                    args.nsid = nsid;
                    args.cntid = cntid;
                    args.cns_specific_id = NVME_CNSSPECID_NONE;
                    args.uuidx = NVME_UUID_NONE,

                    rc = nvme_mi_admin_identify(ctrl, &args);
                }
            }

            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to do nvme identify: "
                          << std::strerror(errno) << '\n';
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to do nvme identify: " << errMsg << '\n';
            }

            auto ex = makeLibNVMeError(errno, rc, "adminIdentify");
            if (ex)
            {
                std::cerr << "fail to do nvme identify: " << ex->description()
                          << '\n';
            }

            self->io.post([cb{cb}, ex, data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb(ex, span);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << endpoint->describe() << "]" << e.what() << '\n';
        auto msg = std::string("Runtime error: ") + e.what();
        std::cerr << msg << '\n';
        io.post([cb{std::move(cb)}, msg]() { cb(makeLibNVMeError(msg), {}); });
        return;
    }
}

static int nvmeMiAdminGetLogTelemetryHostRae(nvme_mi_ctrl_t ctrl, bool /*rae*/,
                                             __u64 offset, __u32 len, void* log)
{
    return nvme_mi_admin_get_log_telemetry_host(ctrl, offset, len, log);
}

// Get Temetery Log header and return the size for hdr + data area (Area 1, 2,
// 3, or maybe 4)
int getTelemetryLogSize(nvme_mi_ctrl_t ctrl, bool host, uint32_t& size)
{
    int rc = 0;
    nvme_telemetry_log log = {};
    auto func = host ? nvmeMiAdminGetLogTelemetryHostRae
                     : nvme_mi_admin_get_log_telemetry_ctrl;

    // Only host telemetry log requires create.
    if (host)
    {
        rc = nvme_mi_admin_get_log_create_telemetry_host(ctrl, &log);
        if (rc != 0)
        {
            std::cerr << "failed to create telemetry host log" << '\n';
            return rc;
        }
    }

    rc = func(ctrl, false, 0, sizeof(log), &log);

    if (rc != 0)
    {
        std::cerr << "failed to retain telemetry log for "
                  << (host ? "host" : "ctrl") << '\n';
        return rc;
    }

    // Restrict the telemetry log to Data Area 1 and 2. Getting Data Area 3
    // OOB is not suitable due to its possible size. Data Area 3 can be up to
    // 30000 data blocks with each block being 512 bytes in size. Restricting
    // to Area 1 and 2.
    size = static_cast<uint32_t>(
               (boost::endian::little_to_native(log.dalb2) + 1)) *
           NVME_LOG_TELEM_BLOCK_SIZE;
    return rc;
}

void NVMeMi::getTelemetryLogChunk(
    nvme_mi_ctrl_t ctrl, bool host, uint64_t offset,
    std::vector<uint8_t>&& data,
    std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)
{
    if (offset >= data.size())
    {
        std::cerr << "[" << device->describe() << "]"
                  << "get telemetry log: offset exceed the log size. "
                  << "offset: " << offset << ", size: " << data.size() << '\n';
        cb(std::make_error_code(std::errc::invalid_argument), {});
        return;
    }

    post([self{shared_from_this()}, ctrl, host, offset, data{std::move(data)},
          cb{std::move(cb)}]() mutable {
        int rc = 0;
        bool rae = true;
        auto func = host ? nvmeMiAdminGetLogTelemetryHostRae
                         : nvme_mi_admin_get_log_telemetry_ctrl;
        uint32_t size = 0;

        // final transaction
        if (offset + nvmeMiXferSize >= data.size())
        {
            rae = false;
        }
        size = std::min(static_cast<uint32_t>(nvmeMiXferSize),
                        static_cast<uint32_t>(data.size() - offset));

        rc = func(ctrl, rae, offset, size, data.data() + offset);

        if (rc < 0)
        {
            std::cerr << "[" << self->device->describe() << "]"
                      << "fail to get chunk for telemetry log: "
                      << std::strerror(errno) << '\n';
            boost::asio::post(self->io,
                              [cb{std::move(cb)}, lastErrno{errno}]() {
                cb(std::make_error_code(static_cast<std::errc>(lastErrno)), {});
            });
            return;
        }
        if (rc > 0)
        {
            std::string_view errMsg =
                statusToString(static_cast<nvme_mi_resp_status>(rc));
            std::cerr << "[" << self->device->describe() << "]"
                      << "fail to get chunk for telemetry log: " << errMsg
                      << '\n';
            boost::asio::post(self->io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::bad_message), {});
            });
            return;
        }

        if (!rae)
        {
            boost::asio::post(
                self->io, [cb{std::move(cb)}, data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb({}, span);
            });
            return;
        }

        offset += size;
        boost::asio::post(self->io,
                          [self, ctrl, host, offset, data{std::move(data)},
                           cb{std::move(cb)}]() mutable {
            self->getTelemetryLogChunk(ctrl, host, offset, std::move(data),
                                       std::move(cb));
        });
    });
}

void NVMeMi::adminGetLogPage(
    nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid, uint32_t nsid, uint8_t lsp,
    uint16_t /*lsi*/,
    std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';
        io.post(
            [cb{std::move(cb)}, errc{degraded.value()}]() { cb(errc, {}); });
        return;
    }

    try
    {
        post([ctrl, nsid, lid, lsp, self{shared_from_this()}, ep{endpoint},
              cb{std::move(cb)}]() {
            std::vector<uint8_t> data;
            std::function<void(void)> logHandler;
            int rc = 0;
            int logId = lid;
            switch (logId)
            {
                case NVME_LOG_LID_ERROR:
                {
                    data.resize(nvmeMiXferSize);
                    // The number of entries for most recent error logs.
                    // Currently we only do one nvme mi transfer for the
                    // error log to avoid blocking other tasks
                    static constexpr int num = nvmeMiXferSize /
                                               sizeof(nvme_error_log_page);
                    nvme_error_log_page* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_error_log_page*>(data.data());

                    rc = nvme_mi_admin_get_log_error(ctrl, num, false, log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get error log" << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_SMART:
                {
                    data.resize(sizeof(nvme_smart_log));
                    nvme_smart_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_smart_log*>(data.data());
                    rc = nvme_mi_admin_get_log_smart(ctrl, nsid, false, log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get smart log" << '\n';
                        break;
                    }
                }
                break;
                    /* Begin of patch context
                     *
                     *
                     *
                     */
                    /*
                     *
                     *
                     * End of patch context
                     */
                case NVME_LOG_LID_FW_SLOT:
                {
                    data.resize(sizeof(nvme_firmware_slot));
                    nvme_firmware_slot* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_firmware_slot*>(data.data());
                    rc = nvme_mi_admin_get_log_fw_slot(ctrl, false, log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get firmware slot" << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_CMD_EFFECTS:
                {
                    data.resize(sizeof(nvme_cmd_effects_log));
                    nvme_cmd_effects_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_cmd_effects_log*>(data.data());

                    // nvme rev 1.3 doesn't support csi,
                    // set to default csi = NVME_CSI_NVM
                    rc = nvme_mi_admin_get_log_cmd_effects(ctrl, NVME_CSI_NVM,
                                                           log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get cmd supported and effects log"
                                  << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_DEVICE_SELF_TEST:
                {
                    data.resize(sizeof(nvme_self_test_log));
                    nvme_self_test_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_self_test_log*>(data.data());
                    rc = nvme_mi_admin_get_log_device_self_test(ctrl, log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get device self test log" << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_CHANGED_NS:
                {
                    data.resize(sizeof(nvme_ns_list));
                    nvme_ns_list* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_ns_list*>(data.data());
                    rc = nvme_mi_admin_get_log_changed_ns_list(ctrl, false,
                                                               log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get changed namespace list"
                                  << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_TELEMETRY_HOST:
                // fall through to NVME_LOG_LID_TELEMETRY_CTRL
                case NVME_LOG_LID_TELEMETRY_CTRL:
                {
                    bool host = lid == NVME_LOG_LID_TELEMETRY_HOST;

                    uint32_t size = 0;
                    rc = getTelemetryLogSize(ctrl, host, size);
                    if (rc == 0)
                    {
                        data.resize(size);
                        logHandler = [self, ctrl, host, data{data},
                                      cb{cb}]() mutable {
                            self->getTelemetryLogChunk(
                                ctrl, host, 0, std::move(data), std::move(cb));
                        };
                    }
                }
                break;
                case NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN:
                {
                    data.resize(sizeof(nvme_lockdown_log));
                    nvme_lockdown_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_lockdown_log*>(data.data());

                    int rc = nvme_mi_admin_get_log_lockdown(ctrl, lsp, log);
                    if (rc != 0)
                    {
                        std::cerr
                            << "[" << ep->describe() << "]"
                            << "fail to get command and feature lockdown log"
                            << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_RESERVATION:
                {
                    data.resize(sizeof(nvme_resv_notification_log));
                    nvme_resv_notification_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_resv_notification_log*>(
                            data.data());

                    int rc = nvme_mi_admin_get_log_reservation(ctrl, false,
                                                               log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get reservation "
                                     "notification log"
                                  << '\n';
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_SANITIZE:
                {
                    data.resize(sizeof(nvme_sanitize_log_page));
                    nvme_sanitize_log_page* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_sanitize_log_page*>(data.data());

                    int rc = nvme_mi_admin_get_log_sanitize(ctrl, false, log);
                    if (rc != 0)
                    {
                        std::cerr << "[" << ep->describe() << "]"
                                  << "fail to get sanitize status log" << '\n';
                        break;
                    }
                }
                break;
                default:
                {
                    std::cerr << "[" << ep->describe() << "]"
                              << "unknown lid for GetLogPage" << '\n';
                    rc = -1;
                    errno = EINVAL;
                }
            }

            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to get log page: " << std::strerror(errno)
                          << '\n';
                logHandler = [cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {});
                };
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to get log pag: " << errMsg << '\n';
                logHandler = [cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), {});
                };
            }

            if (!logHandler)
            {
                logHandler = [cb{cb}, data{std::move(data)}]() mutable {
                    std::span<uint8_t> span{data.data(), data.size()};
                    cb({}, span);
                };
            }
            boost::asio::post(self->io, logHandler);
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << endpoint->describe() << "]"
                  << "NVMeMi adminGetLogPage throws: " << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

void NVMeMi::adminXfer(
    nvme_mi_ctrl_t ctrl, const nvme_mi_admin_req_hdr& adminReq,
    std::span<uint8_t> data, unsigned int timeoutMs,
    std::function<void(const std::error_code&, const nvme_mi_admin_resp_hdr&,
                       std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';
        io.post([cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, {}, {});
        });
        return;
    }

    try
    {
        std::vector<uint8_t> req(sizeof(nvme_mi_admin_req_hdr) + data.size());
        memcpy(req.data(), &adminReq, sizeof(nvme_mi_admin_req_hdr));
        memcpy(req.data() + sizeof(nvme_mi_admin_req_hdr), data.data(),
               data.size());
        post([ctrl, req{std::move(req)}, self{shared_from_this()}, ep{endpoint},
              timeoutMs, cb{std::move(cb)}]() mutable {
            int rc = 0;

            nvme_mi_admin_req_hdr* reqHeader =
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                reinterpret_cast<nvme_mi_admin_req_hdr*>(req.data());
            // set response data size == req DL. Only if data passed is empty
            size_t respDataSize = 0;
            if (req.size() == sizeof(nvme_mi_admin_req_hdr))
            {
                respDataSize =
                    boost::endian::little_to_native<size_t>(reqHeader->dlen);
            }
            off_t respDataOffset =
                boost::endian::little_to_native<off_t>(reqHeader->doff);
            size_t bufSize = sizeof(nvme_mi_admin_resp_hdr) + respDataSize;
            std::vector<uint8_t> buf(bufSize);
            nvme_mi_admin_resp_hdr* respHeader =
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                reinterpret_cast<nvme_mi_admin_resp_hdr*>(buf.data());

            // set timeout
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeoutMs);

            rc = nvme_mi_admin_xfer(ctrl, reqHeader,
                                    req.size() - sizeof(nvme_mi_admin_req_hdr),
                                    respHeader, respDataOffset, &respDataSize);
            // revert to previous timeout
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << "failed to nvme_mi_admin_xfer" << '\n';
                self->io.post([cb{std::move(cb)}, lastErrno{errno}]() {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {}, {});
                });
                return;
            }
            // the MI interface will only consume protocol/io errors
            // The client will take the reponsibility to deal with nvme-mi
            // status flag and nvme status field(cwd3). cmd specific return
            // value (cdw0) is also client's job.

            buf.resize(sizeof(nvme_mi_admin_resp_hdr) + respDataSize);
            self->io.post([cb{std::move(cb)}, data{std::move(buf)}]() mutable {
                std::span<uint8_t> span(
                    data.begin() + sizeof(nvme_mi_admin_resp_hdr), data.end());
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                cb({}, *reinterpret_cast<nvme_mi_admin_resp_hdr*>(data.data()),
                   span);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << endpoint->describe() << "]" << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {}, {});
        });
        return;
    }
}

void NVMeMi::adminFwCommit(
    nvme_mi_ctrl_t ctrl, nvme_fw_commit_ca action, uint8_t slot, bool bpid,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';
        io.post([cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
    try
    {
        nvme_fw_commit_args args{};
        memset(&args, 0, sizeof(args));
        args.args_size = sizeof(args);
        args.action = action;
        args.slot = slot;
        args.bpid = bpid;
        io.post([ctrl, args, cb{std::move(cb)}, ep{endpoint},
                 self{shared_from_this()}]() mutable {
            int rc = nvme_mi_admin_fw_commit(ctrl, &args);
            if (rc < 0)
            {
                std::cerr << "[" << ep->describe() << "]"
                          << "fail to nvme_mi_admin_fw_commit: "
                          << std::strerror(errno) << '\n';
                self->io.post([cb{std::move(cb)}, lastErrno{errno}]() {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       nvme_status_field::NVME_SC_MASK);
                });
                return;
            }
            if (rc >= 0)
            {
                switch (rc & 0x7ff)
                {
                    case NVME_SC_SUCCESS:
                    case NVME_SC_FW_NEEDS_CONV_RESET:
                    case NVME_SC_FW_NEEDS_SUBSYS_RESET:
                    case NVME_SC_FW_NEEDS_RESET:
                        self->io.post([rc, cb{std::move(cb)}]() {
                            cb({}, static_cast<nvme_status_field>(rc));
                        });
                        break;
                    default:
                        std::string_view errMsg = statusToString(
                            static_cast<nvme_mi_resp_status>(rc));
                        std::cerr
                            << "fail to nvme_mi_admin_fw_commit: " << errMsg
                            << '\n';
                        self->io.post([rc, cb{std::move(cb)}]() {
                            cb(std::make_error_code(std::errc::bad_message),
                               static_cast<nvme_status_field>(rc));
                        });
                }
                return;
            }
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << "[" << endpoint->describe() << "]" << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
}

void NVMeMi::adminFwDownloadChunk(
    nvme_mi_ctrl_t ctrl, const std::string& firmwarefile, size_t size,
    size_t offset, int attemptCount,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        std::cerr << "[" << device->describe() << "]"
                  << " MCTP connection is not established" << '\n';
        io.post([cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
    try
    {
        post([ctrl, firmwarefile, size, offset, attemptCount, cb{std::move(cb)},
              self{shared_from_this()}]() mutable {
            std::array<char, nvmeMiXferSize> data = {};
            std::ifstream fwFile(firmwarefile, std::ios::in | std::ios::binary);
            if (fwFile.fail())
            {
                std::cerr << "fail to open fw image file: " << firmwarefile
                          << strerror(errno) << '\n';
                self->io.post([cb{std::move(cb)}]() {
                    cb(std::make_error_code(static_cast<std::errc>(errno)),
                       nvme_status_field::NVME_SC_MASK);
                });
                return;
            }
            fwFile.seekg(static_cast<int64_t>(offset), std::ios::beg);
            nvme_fw_download_args args = {};
            memset(&args, 0, sizeof(args));
            args.args_size = sizeof(args);
            int dataLen =
                static_cast<int>(std::min(size - offset, nvmeMiXferSize));
            fwFile.read((char*)data.data(), dataLen);
            fwFile.close();
            args.offset = offset;
            args.data_len = dataLen;
            args.data = (char*)data.data();
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, downloadDefaultTimeoutMS);
            int rc = nvme_mi_admin_fw_download(ctrl, &args);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
            if (rc < 0)
            {
                if (attemptCount > 0)
                {
                    std::cout << "Retrying the firmware chunk. With Offset :"
                              << offset << " Total firmware Size :" << size
                              << '\n';
                    attemptCount = attemptCount - 1;
                }
                else
                {
                    std::cerr << "fail to nvme_mi_admin_fw_download: "
                              << std::strerror(errno) << '\n';
                    self->io.post([cb{std::move(cb)}]() {
                        cb(std::make_error_code(static_cast<std::errc>(errno)),
                           nvme_status_field::NVME_SC_MASK);
                    });
                    return;
                }
            }
            else
            {
                attemptCount = 3; /* Reset the attempt count*/
                offset = offset + args.data_len;
            }
            if (offset >= size)
            {
                std::cout
                    << "Successfully transferred the firmware. Transfer Size : "
                    << offset << " Total Size :" << size << '\n';
                self->io.post([rc, cb{std::move(cb)}]() {
                    cb({}, static_cast<nvme_status_field>(rc));
                });
                return;
            }
            self->io.post([self, ctrl, firmwarefile, size, offset, attemptCount,
                           cb{std::move(cb)}]() mutable {
                self->adminFwDownloadChunk(ctrl, firmwarefile, size, offset,
                                           attemptCount, std::move(cb));
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << e.what() << '\n';
        io.post([cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
}

void NVMeMi::adminFwDownload(
    nvme_mi_ctrl_t ctrl, std::string firmwarefile,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    size_t offset = 0;
    int tryCount = 3;
    std::ifstream imageFile(firmwarefile,
                            std::ios::in | std::ios::binary | std::ios::ate);
    if (imageFile.fail())
    {
        std::cerr << "Can't open the firmware file: " << std::strerror(errno)
                  << '\n';
        io.post([cb{cb}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
    }
    size_t size = imageFile.tellg();
    imageFile.close();
    adminFwDownloadChunk(ctrl, firmwarefile, size, offset, tryCount,
                         std::move(cb));
}

void NVMeMi::adminSecuritySend(
    nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
    std::span<uint8_t> data,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, proto, protoSpecific, data, cb{cb}]() {
        struct nvme_security_send_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.secp = proto;
        args.spsp0 = protoSpecific & 0xff;
        args.spsp1 = protoSpecific >> 8;
        args.nssf = 0;
        args.data = data.data();
        args.data_len = data.size_bytes();
        args.args_size = sizeof(struct nvme_security_send_args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, tcgDefaultTimeoutMS);
        int status = nvme_mi_admin_security_send(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        self->io.post([cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        std::cerr << "[" << device->describe() << "]"
                  << "adminSecuritySend post failed: " << postErr << '\n';
        io.post([cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminSecurityReceive(
    nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
    uint32_t transferLength,
    std::function<void(const std::error_code&, int nvmeStatus,
                       std::span<uint8_t> data)>&& cb)
{
    if (transferLength > maxNVMeMILength)
    {
        cb(std::make_error_code(std::errc::invalid_argument), -1, {});
        return;
    }

    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, proto, protoSpecific,
                 transferLength, cb{cb}]() {
        std::vector<uint8_t> data(transferLength);

        struct nvme_security_receive_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.secp = proto;
        args.spsp0 = protoSpecific & 0xff;
        args.spsp1 = protoSpecific >> 8;
        args.nssf = 0;
        args.data = data.data();
        args.data_len = data.size();
        args.args_size = sizeof(struct nvme_security_receive_args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, tcgDefaultTimeoutMS);
        int status = nvme_mi_admin_security_recv(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        if (args.data_len > maxNVMeMILength)
        {
            std::cerr << "[" << self->device->describe() << "]"
                      << "nvme_mi_admin_security_send returned excess data, "
                      << args.data_len << '\n';
            self->io.post([cb]() {
                cb(std::make_error_code(std::errc::protocol_error), -1, {});
            });
            return;
        }

        data.resize(args.data_len);
        self->io.post([cb{cb}, nvmeErrno{errno}, status, data]() mutable {
            std::span<uint8_t> span{data.data(), data.size()};
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status, span);
        });
    });
    if (postErr)
    {
        std::cerr << "[" << device->describe() << "]"
                  << "adminSecurityReceive post failed: " << postErr << '\n';
        io.post([cb{std::move(cb)}, postErr]() { cb(postErr, -1, {}); });
    }
}

void NVMeMi::adminNonDataCmd(
    nvme_mi_ctrl_t ctrl, uint8_t opcode, uint32_t cdw1, uint32_t cdw2,
    uint32_t cdw3, uint32_t cdw10, uint32_t cdw11, uint32_t cdw12,
    uint32_t cdw13, uint32_t cdw14, uint32_t cdw15,
    std::function<void(const std::error_code&, int nvmeStatus,
                       uint32_t comptionDw0)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, opcode, cdw1, cdw2, cdw3,
                 cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, cb{cb}]() {
        uint32_t comptionDw0 = 0;
        int nvmeStatus = nvme_mi_admin_admin_passthru(
            ctrl, opcode, 0, 0, cdw1, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13,
            cdw14, cdw15, 0, nullptr, 0, nullptr, 10 * 1000, &comptionDw0);
        self->io.post(
            [cb{cb}, nvmeErrno{errno}, nvmeStatus, comptionDw0]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, nvmeStatus, comptionDw0);
        });
    });
    if (postErr)
    {
        std::cerr << "[" << device->describe() << "]"
                  << "adminNonDataCmd post failed: " << postErr << '\n';
        io.post([cb{std::move(cb)}, postErr]() { cb(postErr, -1, 0); });
    }
}

/* throws a nvme_ex_ptr on failure */
size_t NVMeMi::getBlockSize(nvme_mi_ctrl_t ctrl, size_t lbaFormat)
{
    struct nvme_id_ns id = {};
    std::cout << "getblocksize" << '\n';
    int status = nvme_mi_admin_identify_ns(ctrl, NVME_NSID_ALL, &id);
    auto e = makeLibNVMeError(errno, status, "getBlockSize");
    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::cout << "nlbaf " << (int)id.nlbaf << "lbaf " << (int)lbaFormat << '\n';

    // Sanity check for the value from the drive
    size_t maxLbaf = std::min(63, (int)id.nlbaf);

    // NLBAF is the maximum allowed index (not a count)
    if (lbaFormat > maxLbaf)
    {
        throw makeLibNVMeError("LBA format out of range, maximum is " +
                                   std::to_string(maxLbaf),
                               std::make_shared<common_err::InvalidArgument>());
    }

    return 1 << id.lbaf[lbaFormat].ds;
}

/*
 finished_cb will not be called if submitted_cb is called with a failure.
 */
void NVMeMi::createNamespace(
    nvme_mi_ctrl_t ctrl, uint64_t size, size_t lbaFormat, bool metadataAtEnd,
    std::function<void(nvme_ex_ptr ex)>&& submittedCb,
    std::function<void(nvme_ex_ptr ex, NVMeNSIdentify newid)>&& finishedCb)
{
    std::cout << "createns " << (int)gettid() << '\n';
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, size, lbaFormat, metadataAtEnd,
         submittedCb{submittedCb}, finishedCb{std::move(finishedCb)}]() {
        size_t blockSize = 0;

        try
        {
            blockSize = NVMeMi::getBlockSize(ctrl, lbaFormat);
        }
        // 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)
        catch (nvme_ex_ptr e)
        {
            submittedCb(e);
            return;
        }

        if (size % blockSize != 0)
        {
            auto msg =
                std::string("Size must be a multiple of the block size ") +
                std::to_string(blockSize);
            submittedCb(makeLibNVMeError(
                msg, std::make_shared<common_err::InvalidArgument>()));
            return;
        }

        uint64_t blocks = size / blockSize;

        // TODO: this will become nvme_ns_mgmt_host_sw_specified in a newer
        // libnvme.
        struct nvme_id_ns data = {};
        uint32_t newNsid = 0;

        uint8_t flbas = 0;
        if (metadataAtEnd)
        {
            flbas |= (1 << 4);
        }
        // low 4 bits at 0:3
        flbas |= (lbaFormat & 0xf);
        // high 2 bits at 5:6
        flbas |= ((lbaFormat & 0x30) << 1);

        memset(&data, 0x0, sizeof(data));
        data.nsze = ::htole64(blocks);
        data.ncap = ::htole64(blocks);
        data.flbas = flbas;

        std::cout << "verified " << (int)gettid() << '\n';

        // submission has been verified. Handle the cb in main thread
        // concurrently.
        self->io.post([submittedCb{submittedCb}]() mutable {
            submittedCb(nvme_ex_ptr());
        });
        std::cout << "after submitted_cb " << (int)gettid() << '\n';

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_mgmt_create(ctrl, &data, 0, &newNsid);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        nvme_ex_ptr e = makeLibNVMeError(errno, status, "createVolume");

        NVMeNSIdentify newns = {
            .namespaceId = newNsid,
            .size = size,
            .capacity = size,
            .blockSize = blockSize,
            .lbaFormat = lbaFormat,
            .metadataAtEnd = metadataAtEnd,
        };

        self->io.post([finishedCb{finishedCb}, e, newns]() mutable {
            finishedCb(e, newns);
        });

#if 0
        // TODO testing purposes
        static uint32_t counter = 20;

        printf("createNamespace top, sleeping 5 seconds\n");
        sleep(5);

        uint32_t new_ns = counter++;

        printf("create complete. ns %d\n", new_ns);

        auto err = std::make_error_code(static_cast<std::errc>(0));
        cb(err, 0, new_ns);
#endif
    });

    std::cout << "submitted cb " << (int)gettid() << '\n';

    if (postErr)
    {
        std::cerr << "adminAttachDetachNamespace post failed: " << postErr
                  << '\n';
        auto e = makeLibNVMeError(postErr, -1, "createVolume");
        io.post([submittedCb{std::move(submittedCb)}, e]() { submittedCb(e); });
    }
}

// Deletes a namespace
void NVMeMi::adminDeleteNamespace(
    nvme_mi_ctrl_t ctrl, uint32_t nsid,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, nsid, cb{cb}]() {
        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_mgmt_delete(ctrl, nsid);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        self->io.post([cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        std::cerr << "deleteNamespace post failed: " << postErr << '\n';
        io.post([cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminListNamespaces(
    nvme_mi_ctrl_t ctrl,
    std::function<void(nvme_ex_ptr, std::vector<uint32_t> ns)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, cb{cb}]() {
        int status = 0;
        int nvmeErrno = 0;
        std::vector<uint32_t> ns;
        // sanity in case of bad drives, allows for >1million NSes
        const int maxIter = 1000;

        for (int i = 0; i < maxIter; i++)
        {
            struct nvme_ns_list list = {};
            uint32_t start = NVME_NSID_NONE;
            if (!ns.empty())
            {
                start = ns.back() + 1;
            }
            status = nvme_mi_admin_identify_active_ns_list(ctrl, start, &list);
            nvmeErrno = errno;
            if (status != 0)
            {
                ns.clear();
                break;
            }

            // NOLINTNEXTLINE(modernize-loop-convert)
            for (size_t i = 0; i < NVME_ID_NS_LIST_MAX; i++)
            {
                if (list.ns[i] == 0U)
                {
                    break;
                }
                ns.push_back(list.ns[i]);
            }
            if (list.ns[NVME_ID_NS_LIST_MAX - 1] == 0)
            {
                // all entries read
                break;
            }
        }

        auto ex = makeLibNVMeError(nvmeErrno, status, "adminListNamespaces");
        self->io.post([cb{cb}, ex, ns]() mutable { cb(ex, ns); });
    });
    if (postErr)
    {
        auto ex = makeLibNVMeError("post failed");
        io.post([cb{std::move(cb)}, ex]() { cb(ex, std::vector<uint32_t>()); });
    }
}

// Attaches or detaches a namespace from a controller
void NVMeMi::adminAttachDetachNamespace(
    nvme_mi_ctrl_t ctrl, uint16_t ctrlid, uint32_t nsid, bool attach,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, nsid, attach, ctrlid, cb{cb}]() {
        struct nvme_ctrl_list ctrlList = {};
        struct nvme_ns_attach_args args = {};
        memset(&args, 0x0, sizeof(args));

        // TODO: add this to a newer libnvme
        // uint16_t ctrl_id = nvme_mi_ctrl_id(ctrl);
        uint16_t ctrlId = ctrlid;
        nvme_init_ctrl_list(&ctrlList, 1, &ctrlId);
        args.ctrlist = &ctrlList;
        args.nsid = nsid;
        if (attach)
        {
            args.sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH;
        }
        else
        {
            args.sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH;
        }
        args.args_size = sizeof(args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_attach(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
        self->io.post([cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        std::cerr << "adminAttachDetachNamespace post failed: " << postErr
                  << '\n';
        io.post([cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminSanitize(nvme_mi_ctrl_t ctrl,
                           enum nvme_sanitize_sanact sanact, uint8_t passes,
                           uint32_t /*pattern*/, bool invertPattern,
                           std::function<void(nvme_ex_ptr ex)>&& cb)
{
    std::error_code postErr = tryPost([self{shared_from_this()}, ctrl, sanact,
                                       passes, invertPattern, cb{cb}]() {
        struct nvme_sanitize_nvm_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.args_size = sizeof(args);
        args.sanact = sanact;
        args.owpass = passes;
        args.oipbp = invertPattern;

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, sanitizeDefaultTimeoutMS);
        int status = nvme_mi_admin_sanitize_nvm(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
        std::cout << "san status " << status << "errno " << errno << '\n';

        auto ex = makeLibNVMeError(errno, status, "adminSanitize");
        self->io.post([cb{cb}, ex]() mutable { cb(ex); });
    });
    if (postErr)
    {
        auto ex = makeLibNVMeError("post failed");
        io.post([cb{std::move(cb)}, ex]() { cb(ex); });
    }
}
