#pragma once

#include "message_handler.hpp"

#include <ipmid/api.h>

#include <cstddef>
#include <functional>
#include <map>

namespace command
{

struct CommandID
{
    static constexpr size_t lunBits = 2;
    CommandID(uint32_t command) : command(command) {}

    uint8_t netFnLun() const
    {
        return static_cast<uint8_t>(command >> CHAR_BIT);
    }
    uint8_t netFn() const
    {
        return netFnLun() >> lunBits;
    }
    uint8_t lun() const
    {
        return netFnLun() & ((1 << (lunBits + 1)) - 1);
    }
    uint8_t cmd() const
    {
        return static_cast<uint8_t>(command);
    }
    uint32_t command;
};

/**
 * CommandFunctor is the functor register for commands defined in
 * phosphor-net-ipmid. This would take the request part of the command as a
 * vector and a reference to the message handler. The response part of the
 * command is returned as a vector.
 */
using CommandFunctor = std::function<std::vector<uint8_t>(
    const std::vector<uint8_t>&, std::shared_ptr<message::Handler>&)>;

/**
 * @struct CmdDetails
 *
 * Command details is used to register commands supported in phosphor-net-ipmid.
 */
struct CmdDetails
{
    CommandID command;
    CommandFunctor functor;
    session::Privilege privilege;
    bool sessionless;
};

/**
 * @enum NetFns
 *
 * A field that identifies the functional class of the message. The Network
 * Function clusters IPMI commands into different sets.
 */
enum class NetFns
{
    CHASSIS = (0x00 << 10),
    CHASSIS_RESP = (0x01 << 10),

    BRIDGE = (0x02 << 10),
    BRIDGE_RESP = (0x03 << 10),

    SENSOR = (0x04 << 10),
    SENSOR_RESP = (0x05 << 10),
    EVENT = (0x04 << 10),
    EVENT_RESP = (0x05 << 10),

    APP = (0x06 << 10),
    APP_RESP = (0x07 << 10),

    FIRMWARE = (0x08 << 10),
    FIRMWARE_RESP = (0x09 << 10),

    STORAGE = (0x0A << 10),
    STORAGE_RESP = (0x0B << 10),

    TRANSPORT = (0x0C << 10),
    TRANSPORT_RESP = (0x0D << 10),

    //>>
    RESERVED_START = (0x0E << 10),
    RESERVED_END = (0x2B << 10),
    //<<

    GROUP_EXTN = (0x2C << 10),
    GROUP_EXTN_RESP = (0x2D << 10),

    OEM = (0x2E << 10),
    OEM_RESP = (0x2F << 10),
};

/**
 * @class Entry
 *
 * This is the base class for registering IPMI commands. There are two ways of
 * registering commands to phosphor-net-ipmid, the session related commands and
 * provider commands
 *
 * Every commands has a privilege level which mentions the minimum session
 * privilege level needed to execute the command
 */

class Entry
{
  public:
    Entry(CommandID command, session::Privilege privilege) :
        command(command), privilege(privilege)
    {}

    /**
     * @brief Execute the command
     *
     * Execute the command
     *
     * @param[in] commandData - Request Data for the command
     * @param[in] handler - Reference to the Message Handler
     *
     * @return Response data for the command
     */
    virtual std::vector<uint8_t>
        executeCommand(std::vector<uint8_t>& commandData,
                       std::shared_ptr<message::Handler> handler) = 0;

    auto getCommand() const
    {
        return command;
    }

    auto getPrivilege() const
    {
        return privilege;
    }

    virtual ~Entry() = default;
    Entry(const Entry&) = default;
    Entry& operator=(const Entry&) = default;
    Entry(Entry&&) = default;
    Entry& operator=(Entry&&) = default;

  protected:
    CommandID command;

    // Specifies the minimum privilege level required to execute this command
    session::Privilege privilege;
};

/**
 * @class NetIpmidEntry
 *
 * NetIpmidEntry is used to register commands that are consumed only in
 * phosphor-net-ipmid. The RAKP commands, session commands and user management
 * commands are examples of this.
 *
 * There are certain IPMI commands that can be executed before session can be
 * established like Get System GUID, Get Channel Authentication Capabilities
 * and RAKP commands.
 */
class NetIpmidEntry final : public Entry
{
  public:
    NetIpmidEntry(CommandID command, CommandFunctor functor,
                  session::Privilege privilege, bool sessionless) :
        Entry(command, privilege), functor(functor), sessionless(sessionless)
    {}

    /**
     * @brief Execute the command
     *
     * Execute the command
     *
     * @param[in] commandData - Request Data for the command
     * @param[in] handler - Reference to the Message Handler
     *
     * @return Response data for the command
     */
    std::vector<uint8_t>
        executeCommand(std::vector<uint8_t>& commandData,
                       std::shared_ptr<message::Handler> handler) override;

    virtual ~NetIpmidEntry() = default;
    NetIpmidEntry(const NetIpmidEntry&) = default;
    NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
    NetIpmidEntry(NetIpmidEntry&&) = default;
    NetIpmidEntry& operator=(NetIpmidEntry&&) = default;

  private:
    CommandFunctor functor;

    bool sessionless;
};

/**
 * @class Table
 *
 * Table keeps the IPMI command entries as a sorted associative container with
 * Command ID as the unique key. It has interfaces for registering commands
 * and executing a command.
 */
class Table
{
  private:
    struct Private
    {};

  public:
    explicit Table(const Private&) {}
    Table() = delete;
    ~Table() = default;
    // Command Table is a singleton so copy, copy-assignment, move and
    // move assignment is deleted
    Table(const Table&) = delete;
    Table& operator=(const Table&) = delete;
    Table(Table&&) = default;
    Table& operator=(Table&&) = default;

    /**
     * @brief Get a reference to the singleton Table
     *
     * @return Table reference
     */
    static Table& get()
    {
        static std::shared_ptr<Table> ptr = nullptr;
        if (!ptr)
        {
            ptr = std::make_shared<Table>(Private());
        }
        return *ptr;
    }

    using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;

    /**
     * @brief Register a command
     *
     * Register a command with the command table
     *
     * @param[in] inCommand - Command ID
     * @param[in] entry - Command Entry
     *
     * @return: None
     *
     * @note: Duplicate registrations will be rejected.
     *
     */
    void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);

    /**
     * @brief Execute the command
     *
     * Execute the command for the corresponding CommandID
     *
     * @param[in] inCommand - Command ID to execute.
     * @param[in] commandData - Request Data for the command
     * @param[in] handler - Reference to the Message Handler
     *
     */
    void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
                        std::shared_ptr<message::Handler> handler);

  private:
    CommandTable commandTable;
};

} // namespace command
