#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");
    }
    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, 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_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); });
    }
}
