#pragma once

#include <libpldm/instance-id.h>

#include <phosphor-logging/lg2.hpp>

#include <cerrno>
#include <cstdint>
#include <exception>
#include <expected>
#include <string>
#include <system_error>

PHOSPHOR_LOG2_USING;

namespace pldm
{

/**
 * @class InstanceIdError
 * @brief Exception for PLDM instance ID allocation and management errors.
 */
class InstanceIdError : public std::exception
{
  public:
    InstanceIdError(const InstanceIdError&) noexcept = default;
    InstanceIdError(InstanceIdError&&) noexcept = default;
    InstanceIdError& operator=(const InstanceIdError&) noexcept = default;
    InstanceIdError& operator=(InstanceIdError&&) noexcept = default;
    ~InstanceIdError() noexcept override = default;

    /** @brief Construct with an error code. */
    explicit InstanceIdError(int rc) : rc_(rc), msg_(rcToMsg(rc)) {}

    /** @brief Construct with an error code and a string message (copied). */
    InstanceIdError(int rc, const std::string& m) : rc_(rc), msg_(m) {}

    /** @brief Construct with an error code and a string message (moved). */
    InstanceIdError(int rc, std::string&& m) : rc_(rc), msg_(std::move(m)) {}

    /** @brief Get the error code. */
    int rc() const noexcept
    {
        return rc_;
    }

    /** @brief Get the error message. */
    const std::string& msg() const noexcept
    {
        return msg_;
    }

    /** @brief Convert an error code to a message. */
    static std::string rcToMsg(int rc)
    {
        switch (rc)
        {
            case -EAGAIN:
                return "No free instance ids";
            default:
                return std::system_category().message(rc);
        }
    }

    /** @brief Get the error message (for std::exception). */
    const char* what() const noexcept override
    {
        return msg_.c_str();
    }

  private:
    int rc_;
    std::string msg_;
};

/** @class InstanceId
 *  @brief Implementation of PLDM instance id as per DSP0240 v1.0.0
 */
class InstanceIdDb
{
  public:
    InstanceIdDb()
    {
        int rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
        if (rc)
        {
            throw std::system_category().default_error_condition(rc);
        }
    }

    /** @brief Constructor
     *
     *  @param[in] path - instance ID database path
     */
    InstanceIdDb(const std::string& path)
    {
        int rc = pldm_instance_db_init(&pldmInstanceIdDb, path.c_str());
        if (rc)
        {
            throw std::system_category().default_error_condition(rc);
        }
    }

    ~InstanceIdDb()
    {
        /*
         * Abandon error-reporting. We shouldn't throw an exception from the
         * destructor, and the class has multiple consumers using incompatible
         * logging strategies.
         *
         * Broadly, it should be possible to use strace to investigate.
         */
        pldm_instance_db_destroy(pldmInstanceIdDb);
    }

    /** @brief Allocate an instance ID for the given terminus
     *  @param[in] tid - the terminus ID the instance ID is associated with
     *  @return - PLDM instance id on success, or InstanceIdError on failure
     */
    std::expected<uint8_t, InstanceIdError> next(uint8_t tid)
    {
        uint8_t id;
        int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);

        if (rc)
        {
            std::string msg =
                "Failed to allocate instance ID for EID " +
                std::to_string(tid) + ": " + InstanceIdError::rcToMsg(rc);
            error("Instance ID allocation failed for EID {EID}: {MSG}", "EID",
                  tid, "MSG", msg);
            return std::unexpected(InstanceIdError{rc, std::move(msg)});
        }

        return id;
    }

    /** @brief Mark an instance id as unused
     *  @param[in] tid - the terminus ID the instance ID is associated with
     *  @param[in] instanceId - PLDM instance id to be freed
     */
    void free(uint8_t tid, uint8_t instanceId)
    {
        int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceId);
        if (rc == -EINVAL)
        {
            throw std::runtime_error(
                "Instance ID " + std::to_string(instanceId) + " for TID " +
                std::to_string(tid) + " was not previously allocated");
        }
        if (rc)
        {
            throw std::system_category().default_error_condition(rc);
        }
    }

  private:
    pldm_instance_db* pldmInstanceIdDb = nullptr;
};

} // namespace pldm
