#pragma once

#include "bios_attribute.hpp"
#include "bios_table.hpp"
#include "common/instance_id.hpp"
#include "oem_handler.hpp"
#include "platform_config.hpp"
#include "requester/handler.hpp"

#include <libpldm/bios_table.h>

#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>

#include <functional>
#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{
namespace bios
{
enum class BoundType
{
    LowerBound,
    UpperBound,
    ScalarIncrement,
    MinStringLength,
    MaxStringLength,
    OneOf
};

using AttributeName = std::string;
using AttributeType = std::string;
using ReadonlyStatus = bool;
using DisplayName = std::string;
using Description = std::string;
using MenuPath = std::string;
using CurrentValue = std::variant<int64_t, std::string>;
using DefaultValue = std::variant<int64_t, std::string>;
using OptionString = std::string;
using OptionValue = std::variant<int64_t, std::string>;
using ValueDisplayName = std::string;
using Option =
    std::vector<std::tuple<OptionString, OptionValue, ValueDisplayName>>;
using BIOSTableObj =
    std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
               MenuPath, CurrentValue, DefaultValue, Option>;
using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;

using PendingObj = std::tuple<AttributeType, CurrentValue>;
using PendingAttributes = std::map<AttributeName, PendingObj>;
using Callback = std::function<void()>;

/** @class BIOSConfig
 *  @brief Manager BIOS Attributes
 */
class BIOSConfig
{
  public:
    BIOSConfig() = delete;
    BIOSConfig(const BIOSConfig&) = delete;
    BIOSConfig(BIOSConfig&&) = delete;
    BIOSConfig& operator=(const BIOSConfig&) = delete;
    BIOSConfig& operator=(BIOSConfig&&) = delete;
    ~BIOSConfig() = default;

    /** @brief Construct BIOSConfig
     *  @param[in] jsonDir - The directory where json file exists
     *  @param[in] tableDir - The directory where the persistent table is placed
     *  @param[in] dbusHandler - Dbus Handler
     *  @param[in] fd - socket descriptor to communicate to host
     *  @param[in] eid - MCTP EID of host firmware
     *  @param[in] instanceIdDb - pointer to an InstanceIdDb object
     *  @param[in] handler - PLDM request handler
     *  @param[in] platformConfigHandler - pointer to platform config Handler
     *  @param[in] requestPLDMServiceName - Callback for claiming the PLDM
     *             service name Called only after building BIOS tables.
     */
    explicit BIOSConfig(
        const char* jsonDir, const char* tableDir,
        pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid,
        pldm::InstanceIdDb* instanceIdDb,
        pldm::requester::Handler<pldm::requester::Request>* handler,
        pldm::responder::platform_config::Handler* platformConfigHandler,
        pldm::responder::bios::Callback requestPLDMServiceName);

    /** @brief Set attribute value on dbus and attribute value table
     *  @param[in] entry - attribute value entry
     *  @param[in] size - size of the attribute value entry
     *  @param[in] isBMC - indicates if the attribute is set by BMC
     *  @param[in] updateDBus          - update Attr value D-Bus property
     *                                   if this is set to true
     *  @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property
     *                                   if this is set to true
     *  @return pldm_completion_codes
     */
    int setAttrValue(const void* entry, size_t size, bool isBMC,
                     bool updateDBus = true, bool updateBaseBIOSTable = true);

    /** @brief Remove the persistent tables */
    void removeTables();

    /** @brief Build bios tables(string,attribute,attribute value table)*/
    void buildTables();

    /** @brief Get BIOS table of specified type
     *  @param[in] tableType - The table type
     *  @return The bios table, std::nullopt if the table is unaviliable
     */
    std::optional<Table> getBIOSTable(pldm_bios_table_types tableType);

    /** @brief set BIOS table
     *  @param[in] tableType - Indicates what table is being transferred
     *             {BIOSStringTable=0x0, BIOSAttributeTable=0x1,
     *              BIOSAttributeValueTable=0x2}
     *  @param[in] table - table data
     *  @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property
     *                                   if this is set to true
     *  @return pldm_completion_codes
     */
    int setBIOSTable(uint8_t tableType, const Table& table,
                     bool updateBaseBIOSTable = true);

    /** @brief Construct the BIOS Attributes and build the tables
     *         after receiving system type from entity manager.
     *         Also register the Service Name only if
     *         System specific Bios attributes are supported
     *  @param[in] String - System Type
     *  @param[in] bool - flag to register service name
     *  @return void
     */
    void initBIOSAttributes(const std::string& sysType, bool registerService);

  private:
    /** @enum Index into the fields in the BaseBIOSTable
     */
    enum class Index : uint8_t
    {
        attributeType = 0,
        readOnly,
        displayName,
        description,
        menuPath,
        currentValue,
        defaultValue,
        options,
    };

    const fs::path jsonDir;
    const fs::path tableDir;
    pldm::utils::DBusHandler* const dbusHandler;
    BaseBIOSTable baseBIOSTableMaps;

    /** @brief socket descriptor to communicate to host */
    int fd;

    /** @brief MCTP EID of host firmware */
    uint8_t eid;

    /** @brief pointer to an Instance ID database object, used to obtain PLDM
     * instance IDs.
     */
    pldm::InstanceIdDb* instanceIdDb;

    /** @brief PLDM request handler */
    pldm::requester::Handler<pldm::requester::Request>* handler;

    /** @brief platform config Handler*/
    pldm::responder::platform_config::Handler* platformConfigHandler;

    /** @brief Callback for registering the PLDM service name */
    pldm::responder::bios::Callback requestPLDMServiceName;

    // vector persists all attributes
    using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>;
    BIOSAttributes biosAttributes;

    using propName = std::string;
    using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>;

    using ifaceName = std::string;
    using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>;

    // vector to catch the D-Bus property change signals for BIOS attributes
    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch;

    /** @brief system type/model */
    std::string sysType;

    /** @brief Method to update a BIOS attribute when the corresponding Dbus
     *  property is changed
     *  @param[in] chProperties - list of properties which have changed
     *  @param[in] biosAttrIndex - Index of BIOSAttribute pointer in
     * biosAttributes
     *  @return - none
     */
    void processBiosAttrChangeNotification(
        const DbusChObjProperties& chProperties, uint32_t biosAttrIndex);

    /** @brief Method is used to initiate bios attributes only if system type
     *  is already populated by entity manager.
     *  Register the callback if system type is yet to be populated by Entity
     * manager
     */
    void checkSystemTypeAvailability();

    /** @brief Construct an attribute and persist it
     *  @tparam T - attribute type
     *  @param[in] entry - json entry
     */
    template <typename T>
    void constructAttribute(const Json& entry)
    {
        try
        {
            biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler));
            auto biosAttrIndex = biosAttributes.size() - 1;
            auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();

            if (dBusMap.has_value())
            {
                using namespace sdbusplus::bus::match::rules;
                biosAttrMatch.push_back(
                    std::make_unique<sdbusplus::bus::match_t>(
                        pldm::utils::DBusHandler::getBus(),
                        propertiesChanged(dBusMap->objectPath,
                                          dBusMap->interface),
                        [this, biosAttrIndex](sdbusplus::message_t& msg) {
                    DbusChObjProperties props;
                    std::string iface;
                    msg.read(iface, props);
                    processBiosAttrChangeNotification(props, biosAttrIndex);
                }));

                biosAttrMatch.push_back(
                    std::make_unique<sdbusplus::bus::match_t>(
                        pldm::utils::DBusHandler::getBus(),
                        interfacesAdded() + argNpath(0, dBusMap->objectPath),
                        [this, biosAttrIndex, interface = dBusMap->interface](
                            sdbusplus::message_t& msg) {
                    sdbusplus::message::object_path path;
                    DbusIfacesAdded interfaces;

                    msg.read(path, interfaces);
                    auto ifaceIt = interfaces.find(interface);
                    if (ifaceIt != interfaces.end())
                    {
                        processBiosAttrChangeNotification(ifaceIt->second,
                                                          biosAttrIndex);
                    }
                }));
            }
        }
        catch (const std::exception& e)
        {
            error("Constructs Attribute Error, {ERR_EXCEP}", "ERR_EXCEP",
                  e.what());
        }
    }

    /** Construct attributes and persist them */
    void constructAttributes();

    using ParseHandler = std::function<void(const Json& entry)>;

    /** @brief Helper function to parse json
     *  @param[in] filePath - Path of json file
     *  @param[in] handler - Handler to process each entry in the json
     */
    void load(const fs::path& filePath, ParseHandler handler);

    /** @brief Build String Table and persist it
     *  @return The built string table, std::nullopt if it fails.
     */
    std::optional<Table> buildAndStoreStringTable();

    /** @brief Build attribute table and attribute value table and persist them
     *         Read the BaseBIOSTable from the bios-settings-manager and update
     *         attribute table and attribute value table.
     *
     *  @param[in] stringTable - The string Table
     */
    void buildAndStoreAttrTables(const Table& stringTable);

    /** @brief Persist the table
     *  @param[in] path - Path to persist the table
     *  @param[in] table - The table
     */
    void storeTable(const fs::path& path, const Table& table);

    /** @brief Load bios table to ram
     *  @param[in] path - Path of the table
     *  @return The table, std::nullopt if loading fails
     */
    std::optional<Table> loadTable(const fs::path& path);

    /** @brief Method to decode the attribute name from the string handle
     *
     *  @param[in] stringEntry - string entry from string table
     *  @return the decoded string
     */
    std::string decodeStringFromStringEntry(
        const pldm_bios_string_table_entry* stringEntry);

    /** @brief Method to print the string Handle by passing the attribute Handle
     *         of the bios attribute that got updated
     *
     *  @param[in] handle - the Attribute handle of the bios attribute
     *  @param[in] index - index to the possible value handles
     *  @param[in] attrTable - the attribute table
     *  @param[in] stringTable - the string table
     *  @return string handle from the string table and decoded string to the
     * name handle
     */
    std::string displayStringHandle(uint16_t handle, uint8_t index,
                                    const std::optional<Table>& attrTable,
                                    const std::optional<Table>& stringTable);

    /** @brief Method to trace the bios attribute which got changed
     *
     *  @param[in] attrValueEntry - The attribute value entry to update
     *  @param[in] attrEntry - The attribute table entry
     *  @param[in] isBMC - indicates if the attribute is set by BMC
     */
    void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry,
                         const pldm_bios_attr_table_entry* attrEntry,
                         bool isBMC);

    /** @brief Check the attribute value to update
     *  @param[in] attrValueEntry - The attribute value entry to update
     *  @param[in] attrEntry - The attribute table entry
     *  @param[in] stringTable - The string  table
     *  @return pldm_completion_codes
     */
    int checkAttrValueToUpdate(
        const pldm_bios_attr_val_table_entry* attrValueEntry,
        const pldm_bios_attr_table_entry* attrEntry, Table& stringTable);

    /** @brief Check the attribute table
     *  @param[in] table - The table
     *  @return pldm_completion_codes
     */
    int checkAttributeTable(const Table& table);

    /** @brief Check the attribute value table
     *  @param[in] table - The table
     *  @return pldm_completion_codes
     */
    int checkAttributeValueTable(const Table& table);

    /** @brief Update the BaseBIOSTable property of the D-Bus interface
     */
    void updateBaseBIOSTableProperty();

    /** @brief Listen the PendingAttributes property of the D-Bus interface and
     *         update BaseBIOSTable
     */
    void listenPendingAttributes();

    /** @brief Find attribute handle from bios attribute table
     *  @param[in] attrName - attribute name
     *  @return attribute handle
     */
    uint16_t findAttrHandle(const std::string& attrName);

    /** @brief Listen the PendingAttributes property of the D-Bus interface
     * and update BaseBIOSTable
     *  @param[in] msg - Data associated with subscribed signal
     */
    void constructPendingAttribute(const PendingAttributes& pendingAttributes);
};

} // namespace bios
} // namespace responder
} // namespace pldm
