#include <ipmid/api.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
#include <boost/process/child.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <chrono>
#include <commandutils.hpp>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <map>
#include <random>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/server/object.hpp>
#include <sdbusplus/timer.hpp>
#include <sstream>

static void register_netfn_firmware_functions() __attribute__((constructor));

// oem return code for firmware update control
constexpr ipmi_ret_t IPMI_CC_REQ_INVALID_PHASE = 0xd5;
constexpr ipmi_ret_t IPMI_CC_USB_ATTACH_FAIL = 0x80;

static constexpr bool DEBUG = false;

static constexpr char FW_UPDATE_SERVER_DBUS_NAME[] =
    "xyz.openbmc_project.fwupdate1.server";

static constexpr char FW_UPDATE_SERVER_PATH[] =
    "/xyz/openbmc_project/fwupdate1";
static constexpr char FW_UPDATE_SERVER_INFO_PATH[] =
    "/xyz/openbmc_project/fwupdate1/info";
static constexpr char FW_UPDATE_ACTIVE_INFO_PATH[] =
    "/xyz/openbmc_project/fwupdate1/info/bmc_active";
static constexpr char FW_UPDATE_BACKUP_INFO_PATH[] =
    "/xyz/openbmc_project/fwupdate1/info/bmc_backup";

static constexpr char FW_UPDATE_INTERFACE[] = "xyz.openbmc_project.fwupdate1";
static constexpr char FW_UPDATE_INFO_INTERFACE[] =
    "xyz.openbmc_project.fwupdate1.fwinfo";
static constexpr char FW_UPDATE_SECURITY_INTERFACE[] =
    "xyz.openbmc_project.fwupdate1.security";

constexpr std::size_t operator""_MB(unsigned long long v)
{
    return 1024u * 1024u * v;
}
static constexpr int FIRMWARE_BUFFER_MAX_SIZE = 32_MB;

static constexpr char FIRMWARE_BUFFER_FILE[] = "/tmp/fw-download.bin";
static bool local_download_is_active(void)
{
    struct stat sb;
    if (stat(FIRMWARE_BUFFER_FILE, &sb) < 0)
        return false;
    return true;
}

class fw_update_status_cache
{
  public:
    enum
    {
        FW_STATE_INIT = 0,
        FW_STATE_IDLE,
        FW_STATE_DOWNLOAD,
        FW_STATE_VERIFY,
        FW_STATE_WRITE,
        FW_STATE_READY,
        FW_STATE_ERROR = 0x0f,
        FW_STATE_AC_CYCLE_REQUIRED = 0x83,
    };
    fw_update_status_cache() : _bus(getSdBus())
    {
        _match = std::make_shared<sdbusplus::bus::match::match>(
            *_bus,
            sdbusplus::bus::match::rules::propertiesChanged(
                FW_UPDATE_SERVER_PATH, FW_UPDATE_INTERFACE),
            [&](sdbusplus::message::message &msg) {
                if (DEBUG)
                    std::cerr << "propertiesChanged lambda\n";
                std::map<std::string, ipmi::DbusVariant> props;
                std::vector<std::string> inval;
                std::string iface;
                msg.read(iface, props, inval);
                _parse_props(props);
            });
        _initial_fetch();
    }

    uint8_t state()
    {
        if (DEBUG)
            std::cerr << "fw-state: 0x" << std::hex << (int)_state << '\n';
        if ((_state == FW_STATE_IDLE || _state == FW_STATE_INIT) &&
            local_download_is_active())
        {
            _state = FW_STATE_DOWNLOAD;
            _percent = 0;
        }
        return _state;
    }
    uint8_t percent()
    {
        return _percent;
    }
    std::string msg()
    {
        return _msg;
    }
#ifdef UPDATER_ENABLED
    std::string get_software_obj_path()
    {
        return _software_obj_path;
    }
    void set_software_obj_path(std::string &obj_path)
    {
        _software_obj_path = obj_path;
        _state = FW_STATE_WRITE;
        _percent = 0;
        _match = std::make_shared<sdbusplus::bus::match::match>(
            *_bus,
            sdbusplus::bus::match::rules::propertiesChanged(
                _software_obj_path,
                "xyz.openbmc_project.Software.ActivationProgress"),
            [&](sdbusplus::message::message &msg) {
                if (DEBUG)
                    std::cerr << "propertiesChanged lambda\n";
                std::map<std::string, ipmi::DbusVariant> props;
                std::vector<std::string> inval;
                std::string iface;
                msg.read(iface, props, inval);
                _parse_props(props);
            });
    }
    uint8_t activation_timer_timeout()
    {
        std::cerr << "activation_timer_timout(): increase percentage...\n";
        _percent = _percent + 5;
        std::cerr << "_percent = " << std::string((char *)&_percent) << "\n";
        return _percent;
    }
#endif
  protected:
    void _parse_props(std::map<std::string, ipmi::DbusVariant> &properties)
    {
        if (DEBUG)
            std::cerr << "propertiesChanged (" << properties.size()
                      << " elements)";
        for (const auto &t : properties)
        {
            auto key = t.first;
            auto value = t.second;
            if (key == "state")
            {
                auto state = std::get<std::string>(value);
                if (DEBUG)
                    std::cerr << ", state=" << state;
                if (state == "INIT")
                    _state = FW_STATE_INIT;
                else if (state == "IDLE")
                    _state = FW_STATE_IDLE;
                else if (state == "DOWNLOAD")
                    _state = FW_STATE_DOWNLOAD;
                else if (state == "VERIFY")
                    _state = FW_STATE_VERIFY;
                else if (state == "WRITE")
                    _state = FW_STATE_WRITE;
                else if (state == "READY")
                    _state = FW_STATE_READY;
                else if (state == "ERROR")
                    _state = FW_STATE_ERROR;
                else if (state == "AC_CYCLE_REQUIRED")
                    _state = FW_STATE_AC_CYCLE_REQUIRED;
                else
                {
                    _state = FW_STATE_ERROR;
                    _msg = "internal error";
                }
            }
            else if (key == "percent")
            {
                _percent = std::get<int32_t>(value);
                if (DEBUG)
                    std::cerr << ", pct=" << (int)_percent;
            }
            else if (key == "msg")
            {
                _msg = std::get<std::string>(value);
                if (DEBUG)
                    std::cerr << ", msg='" << _msg << '\'';
            }
            else if (key == "Progress")
            {
                _percent = std::get<uint8_t>(value);
                ;
                if (_percent == 100)
                    _state = FW_STATE_READY;
            }
        }
        if ((_state == FW_STATE_IDLE || _state == FW_STATE_INIT) &&
            local_download_is_active())
        {
            _state = FW_STATE_DOWNLOAD;
            _percent = 0;
        }
        if (DEBUG)
            std::cerr << '\n';
    }
    void _initial_fetch()
    {
#ifndef UPDATER_ENABLED
        auto method = _bus->new_method_call(
            FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_PATH,
            "org.freedesktop.DBus.Properties", "GetAll");
        method.append(FW_UPDATE_INTERFACE);
        if (DEBUG)
            std::cerr << "fetch fw status via dbus...\n";
        try
        {
            auto reply = _bus->call(method);

            std::map<std::string, ipmi::DbusVariant> properties;
            reply.read(properties);
            _parse_props(properties);
        }
        catch (sdbusplus::exception::SdBusError &e)
        {
            std::cerr << "Failed in _initial_fetch(): SDBus Error: " << e.what()
                      << "\n";
            return;
        }
#endif
    }

    std::shared_ptr<sdbusplus::asio::connection> _bus;
    std::shared_ptr<sdbusplus::bus::match::match> _match;
    uint8_t _state = 0;
    uint8_t _percent = 0;
    std::string _msg;

  private:
    std::string _software_obj_path;
};

static fw_update_status_cache fw_update_status;

static std::chrono::steady_clock::time_point fw_random_number_timestamp;
static constexpr int FW_RANDOM_NUMBER_LENGTH = 8;
static constexpr auto FW_RANDOM_NUMBER_TTL = std::chrono::seconds(30);
static uint8_t fw_random_number[FW_RANDOM_NUMBER_LENGTH];

static ipmi_ret_t ipmi_firmware_get_fw_random_number(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    std::random_device rd;
    std::default_random_engine gen(rd());
    std::uniform_int_distribution<> dist{0, 255};

    if (*data_len != 0)
    {
        *data_len = 0;
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    fw_random_number_timestamp = std::chrono::steady_clock::now();

    uint8_t *msg_reply = static_cast<uint8_t *>(response);
    for (int i = 0; i < FW_RANDOM_NUMBER_LENGTH; i++)
        fw_random_number[i] = msg_reply[i] = dist(gen);

    if (DEBUG)
        std::cerr << "FW Rand Num: 0x" << std::hex << (int)msg_reply[0] << " 0x"
                  << (int)msg_reply[1] << " 0x" << (int)msg_reply[2] << " 0x"
                  << (int)msg_reply[3] << " 0x" << (int)msg_reply[4] << " 0x"
                  << (int)msg_reply[5] << " 0x" << (int)msg_reply[6] << " 0x"
                  << (int)msg_reply[7] << '\n';

    *data_len = FW_RANDOM_NUMBER_LENGTH;

    return IPMI_CC_OK;
}

static ipmi_ret_t ipmi_firmware_enter_fw_transfer_mode(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Enter FW transfer mode requested, data_len = "
                  << *data_len << '\n';

    if (*data_len != FW_RANDOM_NUMBER_LENGTH)
    {
        *data_len = 0;
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }
    *data_len = 0;

    auto rq_time = std::chrono::steady_clock::now();
    if (DEBUG)
        std::cerr << "now - fwts = "
                  << std::chrono::duration_cast<std::chrono::microseconds>(
                         rq_time - fw_random_number_timestamp)
                         .count()
                  << " us\n";
    if (std::chrono::duration_cast<std::chrono::microseconds>(
            rq_time - fw_random_number_timestamp)
            .count() > std::chrono::duration_cast<std::chrono::microseconds>(
                           FW_RANDOM_NUMBER_TTL)
                           .count())
    {
        if (DEBUG)
            std::cerr << "key timeout\n";
        return IPMI_CC_PARM_OUT_OF_RANGE;
    }

    uint8_t *msg_request = static_cast<uint8_t *>(request);
    for (int i = 0; i < FW_RANDOM_NUMBER_LENGTH; i++)
    {
        if (fw_random_number[i] != msg_request[i])
        {
            if (DEBUG)
                std::cerr << "key error" << (int)fw_random_number[i]
                          << "!=" << (int)msg_request[i] << "\n";
            return IPMI_CC_INVALID_FIELD_REQUEST;
        }
    }

    if (fw_update_status.state() != fw_update_status_cache::FW_STATE_IDLE
        // TODO: Allowing FW_STATE_INIT here to let image activation available
        // without being in FW_STATE_IDLE, need to fix/adjust the state machine
        // to match xyz.openbmc_project.Software.BMC.Updater service activation
        // mechanism at finer grain
        && fw_update_status.state() != fw_update_status_cache::FW_STATE_INIT)
    {
        if (DEBUG)
            std::cerr << "not in INIT or IDLE\n";
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    // FIXME? c++ doesn't off an option for exclusive file creation
    FILE *fp = fopen(FIRMWARE_BUFFER_FILE, "wx");
    if (!fp)
    {
        if (DEBUG)
            std::cerr << "failed to create buffer file\n";
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    fclose(fp);

    return IPMI_CC_OK;
}

static ipmi_ret_t ipmi_firmware_exit_fw_update_mode(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Exit FW update mode\n";
    *data_len = 0;

    ipmi_ret_t rc = IPMI_CC_OK;
    switch (fw_update_status.state())
    {
        case fw_update_status_cache::FW_STATE_INIT:
        case fw_update_status_cache::FW_STATE_IDLE:
            rc = IPMI_CC_INVALID_FIELD_REQUEST;
            break;
        case fw_update_status_cache::FW_STATE_DOWNLOAD:
            unlink(FIRMWARE_BUFFER_FILE);
        case fw_update_status_cache::FW_STATE_VERIFY:
            break;
        case fw_update_status_cache::FW_STATE_WRITE:
            rc = IPMI_CC_INVALID_FIELD_REQUEST;
            break;
        case fw_update_status_cache::FW_STATE_READY:
        case fw_update_status_cache::FW_STATE_ERROR:
            unlink(FIRMWARE_BUFFER_FILE);
            break;
        case fw_update_status_cache::FW_STATE_AC_CYCLE_REQUIRED:
            rc = IPMI_CC_INVALID_FIELD_REQUEST;
            break;
    }
    if (rc == IPMI_CC_OK)
    {
        std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
        // attempt to reset the state machine -- this may fail
        auto method = bus->new_method_call(
            FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_PATH,
            "org.freedesktop.DBus.Properties", "Abort");
        try
        {
            auto reply = bus->call(method);

            ipmi::DbusVariant retval;
            reply.read(retval);
            if (std::get<int>(retval) != 0)
                rc = IPMI_CC_INVALID_FIELD_REQUEST;
        }
        catch (sdbusplus::exception::SdBusError &e)
        {
            std::cerr << "SDBus Error: " << e.what() << "\n";
            return IPMI_CC_UNSPECIFIED_ERROR;
        }
    }

    return rc;
}

static void post_transfer_complete_handler(
    std::unique_ptr<sdbusplus::bus::match::match> &fw_update_matcher);
static bool request_start_firmware_update(const std::string &uri)
{
    if (DEBUG)
        std::cerr << "request start firmware update()\n";

#ifdef UPDATER_ENABLED
    // fwupdate URIs start with file:// or usb:// or tftp:// etc. By the time
    // the code gets to this point, the file should be transferred start the
    // request (creating a new file in /tmp/images causes the update manager to
    // check if it is ready for activation)
    static std::unique_ptr<sdbusplus::bus::match::match> fw_update_matcher;
    post_transfer_complete_handler(fw_update_matcher);
    std::filesystem::rename(
        uri, "/tmp/images/" +
                 boost::uuids::to_string(boost::uuids::random_generator()()));
#else
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method =
        bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_PATH,
                             FW_UPDATE_INTERFACE, "start");
    if (DEBUG)
        std::cerr << "fwupdate1.start: " << uri << '\n';
    method.append(uri);
    try
    {
        auto reply = bus->call(method);

        uint32_t retval;
        reply.read(retval);
        if (retval != 0)
        {
            if (DEBUG)
                std::cerr << "method returned non-zero: " << retval << "\n";
            return false;
        }
        return true;
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what();
        return false;
    }
#endif
    return true;
}

static bool request_abort_firmware_update()
{
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method =
        bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_PATH,
                             FW_UPDATE_INTERFACE, "abort");
    try
    {
        auto reply = bus->call(method);

        unlink(FIRMWARE_BUFFER_FILE);
        uint32_t retval;
        reply.read(retval);
        if (retval != 0)
            return false;
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what() << "\n";
        unlink(FIRMWARE_BUFFER_FILE);
        return false;
    }
    return true;
}

class transfer_hash_check
{
  public:
    enum hash_check
    {
        CHECK_NOT_REQUESTED = 0,
        CHECK_REQUESTED,
        CHECK_PASSED_SHA2,
        CHECK_RESVD1,
        CHECK_FAILED_SHA2 = 0xe2,
        CHECK_RESVD2 = 0xe3,
    };

  protected:
    EVP_MD_CTX *_ctx;
    std::vector<uint8_t> _expected;
    enum hash_check _check;
    bool _started;

  public:
    transfer_hash_check() : _check(CHECK_NOT_REQUESTED), _started(false)
    {
    }
    ~transfer_hash_check()
    {
        if (_ctx)
        {
            EVP_MD_CTX_destroy(_ctx);
            _ctx = NULL;
        }
    }
    void init(const std::vector<uint8_t> &expected)
    {
        _expected = expected;
        _check = CHECK_REQUESTED;
        _ctx = EVP_MD_CTX_create();
        EVP_DigestInit(_ctx, EVP_sha256());
    }
    void hash(const std::vector<uint8_t> &data)
    {
        if (!_started)
            _started = true;
        EVP_DigestUpdate(_ctx, data.data(), data.size());
    }
    void clear()
    {
        // if not started, nothing to clear
        if (_started)
        {
            if (_ctx)
                EVP_MD_CTX_destroy(_ctx);
            if (_check != CHECK_NOT_REQUESTED)
                _check = CHECK_REQUESTED;
            _ctx = EVP_MD_CTX_create();
            EVP_DigestInit(_ctx, EVP_sha256());
        }
    }
    enum hash_check check()
    {
        if (_check == CHECK_REQUESTED)
        {
            unsigned int len;
            std::vector<uint8_t> digest(EVP_MD_size(EVP_sha256()));
            EVP_DigestFinal(_ctx, digest.data(), &len);
            if (digest == _expected)
            {
                if (DEBUG)
                    std::cerr << "transfer sha2 check passed\n";
                _check = CHECK_PASSED_SHA2;
            }
            else
            {
                if (DEBUG)
                    std::cerr << "transfer sha2 check failed\n";
                _check = CHECK_FAILED_SHA2;
            }
        }
        return _check;
    }
    uint8_t status() const
    {
        return static_cast<uint8_t>(_check);
    }
};

std::shared_ptr<transfer_hash_check> xfer_hash_check;

#ifdef UPDATER_ENABLED
static void activate_image(const char *obj_path)
{
    if (DEBUG)
    {
        std::cerr << "activateImage()...\n";
        std::cerr << "obj_path = " << obj_path << "\n";
    }
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method_call = bus->new_method_call(
        "xyz.openbmc_project.Software.BMC.Updater", obj_path,
        "org.freedesktop.DBus.Properties", "Set");
    method_call.append(
        "xyz.openbmc_project.Software.Activation", "RequestedActivation",
        std::variant<std::string>("xyz.openbmc_project.Software.Activation."
                                  "RequestedActivations.Active"));

    try
    {
        auto method_call_reply = bus->call(method_call);
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "Failed in activate_image(): SDBus Error: " << e.what()
                  << "\n";
        return;
    }
}

static void post_transfer_complete_handler(
    std::unique_ptr<sdbusplus::bus::match::match> &fw_update_matcher)
{
    // Setup timer for watching signal
    static phosphor::Timer timer(
        [&fw_update_matcher]() { fw_update_matcher = nullptr; });

    static phosphor::Timer activation_status_timer([]() {
        if (fw_update_status.activation_timer_timeout() >= 95)
        {
            activation_status_timer.stop();
        }
    });

    timer.start(std::chrono::microseconds(5000000), false);

    // callback function for capturing signal
    auto callback = [&fw_update_matcher](sdbusplus::message::message &m) {
        if (DEBUG)
            std::cerr << "[complete] Match fired\n";
        bool flag = false;

        std::vector<std::pair<
            std::string,
            std::vector<std::pair<std::string, std::variant<std::string>>>>>
            interfaces_properties;

        sdbusplus::message::object_path obj_path;

        try
        {
            m.read(obj_path, interfaces_properties); // Read in the object path
                                                     // that was just created
        }
        catch (std::exception &e)
        {
            std::cerr
                << "[complete] Failed at post_transfer_complete-handler : "
                << e.what() << "\n";
        }
        // constructing response message
        if (DEBUG)
            std::cerr << "[complete] obj path = " << obj_path.str << "\n";
        for (auto &interface : interfaces_properties)
        {
            if (DEBUG)
                std::cerr << "[complete] interface = " << interface.first
                          << "\n";

            if (interface.first == "xyz.openbmc_project.Software.Activation")
            {
                // cancel timer only when
                // xyz.openbmc_project.Software.Activation interface is
                // added

                if (DEBUG)
                    std::cerr << "[complete] Attempt to cancel timer...\n";
                try
                {
                    timer.stop();
                    activation_status_timer.start(
                        std::chrono::microseconds(3000000), true);
                }
                catch (std::exception &e)
                {
                    std::cerr << "[complete] cancel timer error: " << e.what()
                              << "\n";
                }

                fw_update_status.set_software_obj_path(obj_path.str);
                activate_image(obj_path.str.c_str());
                if (DEBUG)
                    std::cerr << "[complete] returned from activeImage()\n";

                fw_update_matcher = nullptr;
            }
        }
    };

    // Adding matcher
    fw_update_matcher = std::make_unique<sdbusplus::bus::match::match>(
        *getSdBus(),
        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
        "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
        callback);
}
#endif

class MappedFile
{
  public:
    MappedFile(const std::string &fname) : addr(nullptr), fsize(0)
    {
        std::error_code ec;
        size_t sz = std::filesystem::file_size(fname, ec);
        int fd = open(fname.c_str(), O_RDONLY);
        if (!ec || fd < 0)
        {
            return;
        }
        void *tmp = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        if (tmp == MAP_FAILED)
        {
            return;
        }
        addr = tmp;
        fsize = sz;
    }

    ~MappedFile()
    {
        if (addr)
        {
            munmap(addr, fsize);
        }
    }
    const uint8_t *data() const
    {
        return static_cast<const uint8_t *>(addr);
    }
    size_t size() const
    {
        return fsize;
    }

  private:
    size_t fsize;
    void *addr;
};

static int transfer_from_file(const std::string &uri, bool move = true)
{
    std::error_code ec;
    if (DEBUG)
        std::cerr << "transfer_from_file(" << uri << ")\n";
    if (move)
    {
        std::filesystem::rename(uri, FIRMWARE_BUFFER_FILE, ec);
    }
    else
    {
        std::filesystem::copy(uri, FIRMWARE_BUFFER_FILE,
                              std::filesystem::copy_options::overwrite_existing,
                              ec);
    }
    if (xfer_hash_check)
    {
        MappedFile mappedfw(uri);
        xfer_hash_check->hash(
            {mappedfw.data(), mappedfw.data() + mappedfw.size()});
    }
    if (ec.value())
    {
        std::cerr << "cp/mv returns: " << ec.message() << "(" << ec.value()
                  << ")\n";
    }
    return ec.value();
}

template <typename... ArgTypes>
static int executeCmd(const char *path, ArgTypes &&... tArgs)
{
    boost::process::child execProg(path, const_cast<char *>(tArgs)...);
    execProg.wait();
    return execProg.exit_code();
}

constexpr char USB_CTRL_PATH[] = "/usr/bin/usb-ctrl";
constexpr char FWUPDATE_MOUNT_POINT[] = "/tmp/usb-fwupd.mnt";
constexpr char FWUPDATE_USB_VOL_IMG[] = "/tmp/usb-fwupd.img";
constexpr char FWUPDATE_USB_DEV_NAME[] = "fw-usb-mass-storage-dev";
constexpr size_t fwPathMaxLength = 255;
static int transfer_from_usb(const std::string &uri)
{
    int ret, sysret;
    char fwpath[fwPathMaxLength];
    if (DEBUG)
        std::cerr << "transfer_from_usb(" << uri << ")\n";
    ret = executeCmd(USB_CTRL_PATH, "mount", FWUPDATE_USB_VOL_IMG,
                     FWUPDATE_MOUNT_POINT);
    if (ret)
    {
        return ret;
    }

    std::string usb_path = std::string(FWUPDATE_MOUNT_POINT) + "/" + uri;
    ret = transfer_from_file(usb_path, false);

    executeCmd(USB_CTRL_PATH, "cleanup", FWUPDATE_USB_VOL_IMG,
               FWUPDATE_MOUNT_POINT);
    return ret;
}

static bool transfer_firmware_from_uri(const std::string &uri)
{
    static constexpr char FW_URI_FILE[] = "file://";
    static constexpr char FW_URI_USB[] = "usb://";
    if (DEBUG)
        std::cerr << "transfer_firmware_from_uri(" << uri << ")\n";
    if (boost::algorithm::starts_with(uri, FW_URI_FILE))
    {
        std::string fname = uri.substr(sizeof(FW_URI_FILE) - 1);
        if (fname != FIRMWARE_BUFFER_FILE)
        {
            return 0 == transfer_from_file(fname);
        }
        return true;
    }
    if (boost::algorithm::starts_with(uri, FW_URI_USB))
    {
        std::string fname = uri.substr(sizeof(FW_URI_USB) - 1);
        return 0 == transfer_from_usb(fname);
    }
    return false;
}

/* Get USB-mass-storage device status: inserted => true, ejected => false */
static int usb_get_status()
{
    static constexpr char usb_gadget_base[] = "/sys/kernel/config/usb_gadget/";
    auto usb_device =
        std::filesystem::path(usb_gadget_base) / FWUPDATE_USB_DEV_NAME;
    std::error_code ec;
    return std::filesystem::exists(usb_device, ec) && !ec;
}

/* Insert the USB-mass-storage device status: success => 0, failure => non-0 */
static int usb_attach_device()
{
    if (usb_get_status())
    {
        return 1;
    }
    int ret =
        executeCmd(USB_CTRL_PATH, "setup", FWUPDATE_USB_VOL_IMG,
                   std::to_string(FIRMWARE_BUFFER_MAX_SIZE / 1_MB).c_str());
    if (!ret)
    {
        ret = executeCmd(USB_CTRL_PATH, "insert", FWUPDATE_USB_DEV_NAME,
                         FWUPDATE_USB_VOL_IMG);
    }
    return ret;
}

/* Eject the USB-mass-storage device status: success => 0, failure => non-0 */
static int usb_detach_device()
{
    if (!usb_get_status())
    {
        return 1;
    }
    return executeCmd(USB_CTRL_PATH, "eject", FWUPDATE_USB_DEV_NAME);
}

constexpr uint8_t controls_init = 0x00;
constexpr uint8_t controls_transfer_started = 0x01;
constexpr uint8_t controls_transfer_completed = 0x02;
constexpr uint8_t controls_transfer_aborted = 0x04;
constexpr uint8_t controls_usb_attached = 0x08;

struct fw_update_control_request
{
    enum knob
    {
        CTRL_GET = 0,
        CTRL_XFER_START,
        CTRL_XFER_COMPLETE,
        CTRL_XFER_ABORT,
        CTRL_SET_FILENAME,
        CTRL_USB_ATTACH,
        CTRL_USB_DETACH,
    } __attribute__((packed));
    enum knob control;
    uint8_t nlen;
    char filename[fwPathMaxLength];
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                        ipmi_request_t request,
                                        ipmi_response_t response,
                                        ipmi_data_len_t data_len,
                                        ipmi_context_t context)
{
    static std::string fw_xfer_uri;

    if (DEBUG)
        std::cerr << "FW update control\n";
    *data_len = 0;

    static uint8_t controls = controls_init;
    ipmi_ret_t rc = IPMI_CC_OK;
    auto ctrl_req = reinterpret_cast<fw_update_control_request *>(request);
    auto ctrl_resp = reinterpret_cast<uint8_t *>(response);

    if (usb_get_status())
    {
        controls |= controls_usb_attached;
    }
    else
    {
        controls &= ~controls_usb_attached;
    }

    switch (ctrl_req->control)
    {
        case fw_update_control_request::CTRL_GET:
            break;
        case fw_update_control_request::CTRL_XFER_START:
        {
            controls |= controls_transfer_started;
            // reset buffer to empty (truncate file)
            std::ofstream out(FIRMWARE_BUFFER_FILE,
                              std::ofstream::binary | std::ofstream::trunc);
            fw_xfer_uri = std::string("file://") + FIRMWARE_BUFFER_FILE;
            if (xfer_hash_check)
            {
                xfer_hash_check->clear();
            }
            if (DEBUG)
                std::cerr << "transfer start\n";
        }
        break;
        case fw_update_control_request::CTRL_XFER_COMPLETE:
        {
            if (usb_get_status())
            {
                rc = IPMI_CC_REQ_INVALID_PHASE;
            }
            // finish transfer based on URI
            if (!transfer_firmware_from_uri(fw_xfer_uri))
            {
                rc = IPMI_CC_UNSPECIFIED_ERROR;
                break;
            }
            // transfer complete
            if (xfer_hash_check)
            {
                if (transfer_hash_check::CHECK_PASSED_SHA2 !=
                    xfer_hash_check->check())
                {
                    if (DEBUG)
                        std::cerr << "xfer_hash_check returns not "
                                     "CHECK_PASSED_SHA2\n";
                    rc = IPMI_CC_UNSPECIFIED_ERROR;
                    break;
                }
            }
            // start the request
            if (!request_start_firmware_update(FIRMWARE_BUFFER_FILE))
            {
                if (DEBUG)
                    std::cerr
                        << "request_start_firmware_update returns failure\n";
                rc = IPMI_CC_UNSPECIFIED_ERROR;
            }
            if (rc == IPMI_CC_OK)
            {
                controls |= controls_transfer_completed;
            }
        }
        break;
        case fw_update_control_request::CTRL_XFER_ABORT:
            if (DEBUG)
                std::cerr << "send abort request\n";
            if (usb_get_status())
            {
                if (0 != usb_detach_device())
                {
                    rc = IPMI_CC_USB_ATTACH_FAIL;
                }
            }
            if (!request_abort_firmware_update())
            {
                if (DEBUG)
                    std::cerr
                        << "abort_start_firmware_update returns failure\n";
                rc = IPMI_CC_UNSPECIFIED_ERROR;
            }
            controls |= controls_transfer_aborted;
            break;
        case fw_update_control_request::CTRL_SET_FILENAME:
            fw_xfer_uri.clear();
            fw_xfer_uri.insert(0, ctrl_req->filename, ctrl_req->nlen);
            break;
        case fw_update_control_request::CTRL_USB_ATTACH:
            if (usb_get_status())
            {
                rc = IPMI_CC_INVALID_FIELD_REQUEST;
            }
            else if (0 != usb_attach_device())
            {
                rc = IPMI_CC_USB_ATTACH_FAIL;
            }
            else
            {
                rc = IPMI_CC_OK;
            }
            break;
        case fw_update_control_request::CTRL_USB_DETACH:
            if (!usb_get_status())
            {
                rc = IPMI_CC_INVALID_FIELD_REQUEST;
            }
            if (0 != usb_detach_device())
            {
                rc = IPMI_CC_USB_ATTACH_FAIL;
            }
            else
            {
                rc = IPMI_CC_OK;
            }
            break;
        default:
            if (DEBUG)
                std::cerr << "control byte " << std::hex << ctrl_req->control
                          << " unknown\n";
            rc = IPMI_CC_INVALID_FIELD_REQUEST;
            break;
    }

    if (rc == IPMI_CC_OK)
    {
        *ctrl_resp = controls;
        *data_len = sizeof(*ctrl_resp);
    }

    return rc;
}

struct fw_version_info
{
    uint8_t id_tag;
    uint8_t major;
    uint8_t minor;
    uint32_t build;
    uint32_t build_time;
    uint32_t update_time;
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_fw_version_info(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW Version Info\n";

    // Byte 1 - Count (N) Number of devices data is being returned for.
    // Byte 2 - ID Tag 00 – reserved 01 – BMC Active Image 02 – BBU Active Image
    //                 03 – BMC Backup Image 04 – BBU Backup Image 05 – BBR
    //                 Image
    // Byte 3 - Major Version Number
    // Byte 4 - Minor Version Number
    // Bytes 5:8 - Build Number
    // Bytes 9:12 - Build Timestamp Format: LSB first, same format as SEL
    // timestamp
    // Bytes 13:16 - Update Timestamp
    // Bytes - 17:(15xN) - Repeat of 2 through 16

    uint8_t count = 0;
    auto ret_count = reinterpret_cast<uint8_t *>(response);
    auto info = reinterpret_cast<struct fw_version_info *>(ret_count + 1);

    for (uint8_t id_tag = 1; id_tag < 6; id_tag++)
    {
        const char *fw_path;
        switch (id_tag)
        {
            case 1:
                fw_path = FW_UPDATE_ACTIVE_INFO_PATH;
                break;
            case 2:
                fw_path = FW_UPDATE_BACKUP_INFO_PATH;
                break;
            case 3:
            case 4:
            case 5:
                continue; // skip for now
                break;
        }
        std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
        auto method =
            bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, fw_path,
                                 "org.freedesktop.DBus.Properties", "GetAll");
        method.append(FW_UPDATE_INFO_INTERFACE);
        std::vector<std::pair<std::string, ipmi::DbusVariant>> properties;
        try
        {
            auto reply = bus->call(method);

            if (reply.is_method_error())
                continue;

            reply.read(properties);
        }
        catch (sdbusplus::exception::SdBusError &e)
        {
            std::cerr << "SDBus Error: " << e.what();
            return IPMI_CC_UNSPECIFIED_ERROR;
        }
        uint8_t major = 0;
        uint8_t minor = 0;
        uint32_t build = 0;
        int32_t build_time = 0;
        int32_t update_time = 0;
        for (const auto &t : properties)
        {
            auto key = t.first;
            auto value = t.second;
            if (key == "version")
            {
                auto strver = std::get<std::string>(value);
                std::stringstream ss;
                ss << std::hex << strver;
                uint32_t t;
                ss >> t;
                major = t;
                ss.ignore();
                ss >> t;
                minor = t;
                ss.ignore();
                ss >> build;
            }
            else if (key == "build_time")
            {
                build_time = std::get<int32_t>(value);
            }
            else if (key == "update_time")
            {
                update_time = std::get<int32_t>(value);
            }
        }

        info->id_tag = id_tag;
        info->major = major;
        info->minor = minor;
        info->build = build;
        info->build_time = build_time;
        info->update_time = update_time;
        count++;
        info++;
    }
    *ret_count = count;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = sizeof(count) + count * sizeof(*info);

    return rc;
}

struct fw_security_revision_info
{
    uint8_t id_tag;
    uint16_t sec_rev;
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_fw_security_revision(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW security revision info\n";

    // Byte 1 - Count (N) Number of devices data is being returned for.
    // Byte 2 - ID Tag 00 – reserved 01 – BMC Active Image 02 – BBU Active Image
    //                 03 – BMC Backup Image 04 – BBU Backup Image 05 – BBR
    //                 Image
    // Byte 3 - Major Version Number
    // Byte 4 - Minor Version Number
    // Bytes 5:8 - Build Number
    // Bytes 9:12 - Build Timestamp Format: LSB first, same format as SEL
    // timestamp
    // Bytes 13:16 - Update Timestamp
    // Bytes - 17:(15xN) - Repeat of 2 through 16

    uint8_t count = 0;
    auto ret_count = reinterpret_cast<uint8_t *>(response);
    auto info =
        reinterpret_cast<struct fw_security_revision_info *>(ret_count + 1);

    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    for (uint8_t id_tag = 1; id_tag < 6; id_tag++)
    {
        const char *fw_path;
        switch (id_tag)
        {
            case 1:
                fw_path = FW_UPDATE_ACTIVE_INFO_PATH;
                break;
            case 2:
                fw_path = FW_UPDATE_BACKUP_INFO_PATH;
                break;
            case 3:
            case 4:
            case 5:
                continue; // skip for now
                break;
        }
        auto method =
            bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, fw_path,
                                 "org.freedesktop.DBus.Properties", "GetAll");
        method.append(FW_UPDATE_INFO_INTERFACE, "security_version");
        ipmi::DbusVariant sec_rev;
        try
        {
            auto reply = bus->call(method);

            if (reply.is_method_error())
                continue;

            reply.read(sec_rev);
        }
        catch (sdbusplus::exception::SdBusError &e)
        {
            std::cerr << "SDBus Error: " << e.what();
            return IPMI_CC_UNSPECIFIED_ERROR;
        }

        info->id_tag = id_tag;
        info->sec_rev = std::get<int>(sec_rev);
        count++;
        info++;
    }
    *ret_count = count;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = sizeof(count) + count * sizeof(*info);

    return rc;
}

struct fw_channel_size
{
    uint8_t channel_id;
    uint32_t channel_size;
} __attribute__((packed));

enum
{
    CHANNEL_RESVD = 0,
    CHANNEL_KCS,
    CHANNEL_RMCP_PLUS,
    CHANNEL_USB_DATA,
    CHANNEL_USB_MASS_STORAGE,
} channel_transfer_type;

static ipmi_ret_t ipmi_firmware_max_transfer_size(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW max transfer size\n";

    // Byte 1 - Count (N) Number of devices data is being returned for.
    // Byte 2 - ID Tag 00 – reserved 01 – kcs 02 – rmcp+,
    //                 03 – usb data, 04 – usb mass storage
    // Byte 3-6 - transfer size (little endian)
    // Bytes - 7:(5xN) - Repeat of 2 through 6

    uint8_t count = 0;
    auto ret_count = reinterpret_cast<uint8_t *>(response);
    auto info = reinterpret_cast<struct fw_channel_size *>(ret_count + 1);

    info->channel_id = CHANNEL_KCS;
    info->channel_size = 128;
    info++;
    count++;

    info->channel_id = CHANNEL_RMCP_PLUS;
    info->channel_size = 50 * 1024;
    info++;
    count++;

    /*
    info->channel_id = CHANNEL_USB_MASS_STORAGE;
    info->channel_size = 128;
    info++;
    count++;
    */

    *ret_count = count;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = sizeof(count) + count * sizeof(*info);

    return rc;
}

enum
{
    EXEC_CTX_RESVD = 0,
    EXEC_CTX_FULL_LINUX = 0x10,
    EXEC_CTX_SAFE_MODE_LINUX = 0x11,
} bmc_execution_context;

struct fw_execution_context
{
    uint8_t context;
    uint8_t image_selection;
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_fw_execution_context(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW execution context\n";

    // Byte 1 - execution context
    //          0x10 - full linux stack, 0x11 - safe-mode linux stack
    // Byte 2 - current image selection
    //          1 - primary, 2 - secondary

    auto info = reinterpret_cast<struct fw_execution_context *>(response);
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method =
        bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_PATH,
                             "org.freedesktop.DBus.Properties", "GetAll");
    method.append(FW_UPDATE_SECURITY_INTERFACE);
    int active_img;
    bool safe_mode;
    std::string cert;
    try
    {
        auto reply = bus->call(method);

        if (!reply.is_method_error())
        {
            std::vector<std::pair<std::string, ipmi::DbusVariant>> properties;
            reply.read(properties);

            for (const auto &t : properties)
            {
                auto key = t.first;
                auto value = t.second;
                if (key == "active_partition")
                {
                    active_img = std::get<int>(value);
                }
                else if (key == "safe_mode")
                {
                    safe_mode = std::get<bool>(value);
                }
            }
        }
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what();
        return IPMI_CC_UNSPECIFIED_ERROR;
    }

    if (safe_mode)
        info->context = EXEC_CTX_SAFE_MODE_LINUX;
    else
        info->context = EXEC_CTX_FULL_LINUX;

    info->image_selection = active_img;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = sizeof(*info);

    return rc;
}

struct fw_update_status_response
{
    uint8_t status;
    uint8_t percent;
    uint8_t check;
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                           ipmi_request_t request,
                                           ipmi_response_t response,
                                           ipmi_data_len_t data_len,
                                           ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW update status\n";

    // Byte 1 - status (0=init, 1=idle, 2=download, 3=validate, 4=write,
    //                  5=ready, f=error, 83=ac cycle required)
    // Byte 2 - percent
    // Byte 3 - integrity check status (0=none, 1=req, 2=sha2ok, e2=sha2fail)

    auto fw_status =
        reinterpret_cast<struct fw_update_status_response *>(response);

    fw_status->status = fw_update_status.state();
    fw_status->percent = fw_update_status.percent();
    fw_status->check = xfer_hash_check ? xfer_hash_check->status() : 0;

    // Status code.
    *data_len = sizeof(*fw_status);
    return IPMI_CC_OK;
}

static constexpr uint8_t FW_UPDATE_OPTIONS_NO_DOWNREV = (1 << 0);
static constexpr uint8_t FW_UPDATE_OPTIONS_DEFER_RESTART = (1 << 1);
static constexpr uint8_t FW_UPDATE_OPTIONS_SHA2_CHECK = (1 << 2);
static constexpr uint8_t FW_UPDATE_OPTIONS_RESVD1 = (1 << 3);
struct fw_update_options_request
{
    uint8_t mask;
    uint8_t options;
} __attribute__((packed));

bool fw_update_set_dbus_property(const std::string &path,
                                 const std::string &iface,
                                 const std::string &name,
                                 ipmi::DbusVariant value)
{
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method =
        bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, path.c_str(),
                             "org.freedesktop.DBus.Properties", "Set");
    method.append(iface, name, value);
    try
    {
        auto reply = bus->call(method);
        auto err = reply.is_method_error();
        if (err)
            if (DEBUG)
                std::cerr << "failed to set prop " << path << '/' << iface
                          << '.' << name << '\n';
        return err;
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what();
        return false;
    }
}

uint32_t fw_update_options = 0;
static ipmi_ret_t ipmi_firmware_update_options(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get/set FW update options\n";

    // request:
    // Byte 1 - mask
    // Byte 2 - options
    // Byte 3-34 - optional integrity check expected value
    // response:
    // Byte 1 - set options

    auto fw_options =
        reinterpret_cast<struct fw_update_options_request *>(request);

    const char *path = FW_UPDATE_SERVER_INFO_PATH;
    const char *iface = FW_UPDATE_SECURITY_INTERFACE;
    if ((fw_options->mask & FW_UPDATE_OPTIONS_NO_DOWNREV) &&
        (fw_options->options & FW_UPDATE_OPTIONS_NO_DOWNREV) !=
            (fw_update_options & FW_UPDATE_OPTIONS_NO_DOWNREV))
    {
        if (fw_options->options & FW_UPDATE_OPTIONS_NO_DOWNREV)
        {
            fw_update_options |= FW_UPDATE_OPTIONS_NO_DOWNREV;
        }
        else
        {
            fw_update_options &= ~FW_UPDATE_OPTIONS_NO_DOWNREV;
            // send dbus
        }
        const char *name = "inhibit_downgrade";
        fw_update_set_dbus_property(
            path, iface, name,
            (bool)(!!(fw_update_options & FW_UPDATE_OPTIONS_NO_DOWNREV)));
    }
    if ((fw_options->mask & FW_UPDATE_OPTIONS_DEFER_RESTART) &&
        (fw_options->options & FW_UPDATE_OPTIONS_DEFER_RESTART) !=
            (fw_update_options & FW_UPDATE_OPTIONS_DEFER_RESTART))
    {
        if (fw_options->options & FW_UPDATE_OPTIONS_DEFER_RESTART)
        {
            fw_update_options |= FW_UPDATE_OPTIONS_DEFER_RESTART;
        }
        else
        {
            fw_update_options &= ~FW_UPDATE_OPTIONS_DEFER_RESTART;
        }
        const char *name = "defer_restart";
        fw_update_set_dbus_property(
            path, iface, name,
            (bool)(!!(fw_update_options & FW_UPDATE_OPTIONS_DEFER_RESTART)));
    }
    if (fw_options->mask & FW_UPDATE_OPTIONS_SHA2_CHECK)
    {
        auto hash_size = EVP_MD_size(EVP_sha256());
        if (fw_options->options & FW_UPDATE_OPTIONS_SHA2_CHECK)
        {
            if (*data_len != (sizeof(*fw_options) + hash_size))
            {
                *data_len = 0;
                return IPMI_CC_REQ_DATA_LEN_INVALID;
            }
            xfer_hash_check = std::make_shared<transfer_hash_check>();
            auto exp_hash = reinterpret_cast<uint8_t *>(fw_options + 1);
            xfer_hash_check->init({exp_hash, exp_hash + hash_size});
            fw_update_options |= FW_UPDATE_OPTIONS_SHA2_CHECK;
        }
        else
        {
            fw_update_options &= ~FW_UPDATE_OPTIONS_SHA2_CHECK;
            // delete the xfer_hash_check object
            xfer_hash_check.reset();
        }
    }
    auto options_rsp = reinterpret_cast<uint8_t *>(response);
    *options_rsp = fw_update_options;

    if (DEBUG)
        std::cerr << "current fw_update_options = " << std::hex
                  << fw_update_options << '\n';
    // Status code.
    *data_len = sizeof(*options_rsp);
    return IPMI_CC_OK;
}

struct fw_cert_info
{
    uint16_t cert_len;
    uint64_t serial;
    uint8_t subject_len;
    char subject[255];
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_root_cert_info(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW root cert info\n";

    // request:
    // Byte 1 - certificate ID: request which certificate (ignored)

    // response:
    // Byte 1-2  - certificate length (little endian)
    // Byte 3-10 - serial number (little endian)
    // Byte 11   - subject length
    // Byte 12-N - subject data

    auto cert_info = reinterpret_cast<struct fw_cert_info *>(response);
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method = bus->new_method_call(
        FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_INFO_PATH,
        "org.freedesktop.DBus.Properties", "GetAll");
    method.append(FW_UPDATE_SECURITY_INTERFACE);
    std::string subject;
    uint64_t serial;
    std::string cert;
    try
    {
        auto reply = bus->call(method);

        std::vector<std::pair<std::string, ipmi::DbusVariant>> properties;
        reply.read(properties);

        for (const auto &t : properties)
        {
            auto key = t.first;
            auto value = t.second;
            if (key == "certificate_subject")
            {
                subject = std::get<std::string>(value);
            }
            else if (key == "cetificate_serial")
            {
                serial = std::get<uint64_t>(value);
            }
            else if (key == "certificate")
            {
                cert = std::get<std::string>(value);
            }
        }
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what();
        return IPMI_CC_UNSPECIFIED_ERROR;
    }

    cert_info->cert_len = cert.size();
    cert_info->serial = serial;
    // truncate subject so it fits in the 255-byte array (if necessary)
    if (subject.size() > sizeof(cert_info->subject))
        subject.resize(sizeof(cert_info->subject));
    cert_info->subject_len = subject.size();
    std::copy(subject.begin(), subject.end(), cert_info->subject);

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    // make sure to account for the *actual* size of the subject
    *data_len = sizeof(*cert_info) - sizeof(cert_info->subject) +
                cert_info->subject_len;

    return rc;
}

struct fw_cert_data_req
{
    uint8_t cert_id;
    uint16_t offset;
    uint16_t count;
} __attribute__((packed));

static ipmi_ret_t ipmi_firmware_get_root_cert_data(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Get FW root cert data\n";

    // request:
    // Byte 1 - certificate ID: request which certificate (ignored)
    // Byte 2-3 - offset within cert to start at
    // Byte 4-5 - number of bytes to return

    // response:
    // Byte 1-N  - certificate data

    if (*data_len != sizeof(fw_cert_data_req))
        return IPMI_CC_REQ_DATA_LEN_INVALID;

    auto cert_data_req = reinterpret_cast<struct fw_cert_data_req *>(request);
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    auto method = bus->new_method_call(
        FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_INFO_PATH,
        "org.freedesktop.DBus.Properties", "Get");
    method.append(FW_UPDATE_SECURITY_INTERFACE, "certificate");
    ipmi::DbusVariant cert;
    try
    {
        auto reply = bus->call(method);
        reply.read(cert);
    }
    catch (sdbusplus::exception::SdBusError &e)
    {
        std::cerr << "SDBus Error: " << e.what();
        return IPMI_CC_UNSPECIFIED_ERROR;
    }
    auto cert_data = std::get<std::string>(cert);

    if (cert_data_req->offset >= cert_data.size())
    {
        *data_len = 0;
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    auto first = cert_data.begin() + cert_data_req->offset;
    auto last = first + cert_data_req->count;
    if (last > cert_data.end())
        last = cert_data.end();

    auto data_out = reinterpret_cast<char *>(response);
    std::copy(first, last, data_out);

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = (last - first);

    return rc;
}

static ipmi_ret_t ipmi_firmware_write_data(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                           ipmi_request_t request,
                                           ipmi_response_t response,
                                           ipmi_data_len_t data_len,
                                           ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "write fw data (" << *data_len << " bytes)\n";

    auto bytes_in = *data_len;
    *data_len = 0;
    if (fw_update_status.state() != fw_update_status_cache::FW_STATE_DOWNLOAD)
        return IPMI_CC_INVALID;

    std::ofstream out(FIRMWARE_BUFFER_FILE,
                      std::ofstream::binary | std::ofstream::app);
    if (!out)
    {
        return IPMI_CC_UNSPECIFIED_ERROR;
    }
    if (out.tellp() > FIRMWARE_BUFFER_MAX_SIZE)
    {
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    auto data = reinterpret_cast<uint8_t *>(request);
    out.write(reinterpret_cast<char *>(data), bytes_in);
    out.close();
    if (xfer_hash_check)
    {
        xfer_hash_check->hash({data, data + bytes_in});
    }

    // Status code.
    return IPMI_CC_OK;
}

static constexpr char NOT_IMPLEMENTED[] = "NOT IMPLEMENTED";

static ipmi_ret_t ipmi_firmware_wildcard_handler(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    if (DEBUG)
        std::cerr << "Handling stubbed Netfn:[0x" << std::hex << +netfn
                  << "], Cmd:[0x" << std::hex << +cmd << "]\n";

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;

    *data_len = sizeof(NOT_IMPLEMENTED);

    // Now pack actual response
    char *msg_reply = static_cast<char *>(response);
    std::copy(std::begin(NOT_IMPLEMENTED), std::end(NOT_IMPLEMENTED),
              msg_reply);

    return rc;
}

struct intc_app_get_buffer_size_resp
{
    uint8_t kcs_size;
    uint8_t ipmb_size;
} __attribute__((packed));

static constexpr int KCS_MAX_BUFFER_SIZE = 63;
static constexpr int IPMB_MAX_BUFFER_SIZE = 128;
static ipmi_ret_t ipmi_intel_app_get_buffer_size(
    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
{
    auto msg_reply =
        reinterpret_cast<intc_app_get_buffer_size_resp *>(response);
    // for now this is hard coded; really this number is dependent on
    // the BMC kcs driver as well as the host kcs driver....
    // we can't know the latter.
    msg_reply->kcs_size = KCS_MAX_BUFFER_SIZE / 4;
    msg_reply->ipmb_size = IPMB_MAX_BUFFER_SIZE / 4;
    *data_len = sizeof(*msg_reply);

    return IPMI_CC_OK;
}

static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_VERSION_INFO = 0x20;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_SEC_VERSION_INFO = 0x21;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_UPD_CHAN_INFO = 0x22;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_BMC_EXEC_CTX = 0x23;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_ROOT_CERT_INFO = 0x24;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_ROOT_CERT_DATA = 0x25;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_UPDATE_RAND_NUM = 0x26;
static constexpr ipmi_cmd_t IPMI_CMD_FW_SET_FW_UPDATE_MODE = 0x27;
static constexpr ipmi_cmd_t IPMI_CMD_FW_EXIT_FW_UPDATE_MODE = 0x28;
static constexpr ipmi_cmd_t IPMI_CMD_FW_UPDATE_CONTROL = 0x29;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_STATUS = 0x2a;
static constexpr ipmi_cmd_t IPMI_CMD_FW_SET_FW_UPDATE_OPTIONS = 0x2b;
static constexpr ipmi_cmd_t IPMI_CMD_FW_IMAGE_WRITE = 0x2c;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_TIMESTAMP = 0x2d;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_UPDATE_ERR_MSG = 0xe0;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_REMOTE_FW_INFO = 0xf0;

static constexpr ipmi_netfn_t NETFUN_INTC_APP = 0x30;
static constexpr ipmi_cmd_t IPMI_CMD_INTC_GET_BUFFER_SIZE = 0x66;

static void register_netfn_firmware_functions()
{
    // guarantee that we start with an already timed out timestamp
    fw_random_number_timestamp =
        std::chrono::steady_clock::now() - FW_RANDOM_NUMBER_TTL;

    unlink(FIRMWARE_BUFFER_FILE);

    // <Get BT Interface Capabilities>
    if (DEBUG)
        std::cerr << "Registering firmware update commands\n";

    // get firmware version information
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_VERSION_INFO,
                           NULL, ipmi_firmware_get_fw_version_info,
                           PRIVILEGE_ADMIN);

    // get firmware security version information
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_SEC_VERSION_INFO,
                           NULL, ipmi_firmware_get_fw_security_revision,
                           PRIVILEGE_ADMIN);

    // get channel information (max transfer sizes)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_UPD_CHAN_INFO,
                           NULL, ipmi_firmware_max_transfer_size,
                           PRIVILEGE_ADMIN);

    // get bmc execution context
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_BMC_EXEC_CTX, NULL,
                           ipmi_firmware_get_fw_execution_context,
                           PRIVILEGE_ADMIN);

    // get root certificate information
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_ROOT_CERT_INFO,
                           NULL, ipmi_firmware_get_root_cert_info,
                           PRIVILEGE_ADMIN);

    // get root certificate data
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_ROOT_CERT_DATA,
                           NULL, ipmi_firmware_get_root_cert_data,
                           PRIVILEGE_ADMIN);

    // generate bmc fw update random number (for enter fw tranfer mode)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_UPDATE_RAND_NUM,
                           NULL, ipmi_firmware_get_fw_random_number,
                           PRIVILEGE_ADMIN);

    // enter firmware update mode
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_SET_FW_UPDATE_MODE,
                           NULL, ipmi_firmware_enter_fw_transfer_mode,
                           PRIVILEGE_ADMIN);

    // exit firmware update mode
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_EXIT_FW_UPDATE_MODE,
                           NULL, ipmi_firmware_exit_fw_update_mode,
                           PRIVILEGE_ADMIN);

    // firmware control mechanism (set filename, usb, etc.)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_UPDATE_CONTROL, NULL,
                           ipmi_firmware_control, PRIVILEGE_ADMIN);

    // get firmware update status
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_STATUS, NULL,
                           ipmi_firmware_get_status, PRIVILEGE_ADMIN);

    // set firmware update options (no downgrade, etc.)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_SET_FW_UPDATE_OPTIONS,
                           NULL, ipmi_firmware_update_options, PRIVILEGE_ADMIN);

    // write image data
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_IMAGE_WRITE, NULL,
                           ipmi_firmware_write_data, PRIVILEGE_ADMIN);

    // get update timestamps
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_TIMESTAMP, NULL,
                           ipmi_firmware_wildcard_handler, PRIVILEGE_ADMIN);

    // get error message (when in error state)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_UPDATE_ERR_MSG,
                           NULL, ipmi_firmware_wildcard_handler,
                           PRIVILEGE_ADMIN);

    // get remote firmware information (PSU, HSBP, etc.)
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_REMOTE_FW_INFO,
                           NULL, ipmi_firmware_wildcard_handler,
                           PRIVILEGE_ADMIN);

    // <Wildcard Command>
    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_WILDCARD, NULL,
                           ipmi_firmware_wildcard_handler, PRIVILEGE_ADMIN);

    // get buffer size is used by fw update (exclusively?)
    ipmi_register_callback(NETFUN_INTC_APP, IPMI_CMD_INTC_GET_BUFFER_SIZE, NULL,
                           ipmi_intel_app_get_buffer_size, PRIVILEGE_USER);
    return;
}
