#include "bios_parser.hpp"

#include "bios_table.hpp"
#include "utils.hpp"

#include <cassert>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <optional>
#include <set>

#include "libpldm/bios.h"
#include "libpldm/bios_table.h"

namespace bios_parser
{

using namespace pldm::utils;
using Json = nlohmann::json;
namespace fs = std::filesystem;
using namespace pldm::responder::bios;

const std::vector<Json> emptyJsonList{};
const Json emptyJson{};

using AttrType = uint8_t;
using Table = std::vector<uint8_t>;
using BIOSJsonName = std::string;
using AttrLookup = std::map<AttrName, std::optional<DBusMapping>>;

const std::set<std::string> SupportedDbusPropertyTypes = {
    "bool",     "uint8_t", "int16_t",  "uint16_t", "int32_t",
    "uint32_t", "int64_t", "uint64_t", "double",   "string"};

using BIOSStringHandler =
    std::function<int(const Json& entry, Strings& strings)>;
using AttrLookupHandler = std::function<int(const Json& entry, AttrLookup)>;
using typeHandler = std::function<int(const Json& entry)>;

Strings BIOSStrings;
AttrLookup BIOSAttrLookup;

const Strings& getStrings()
{
    return BIOSStrings;
}

int parseBIOSJsonFile(const fs::path& dirPath, const std::string& fileName,
                      Json& fileData)
{
    int rc = 0;

    fs::path filePath = dirPath / fileName;

    std::ifstream jsonFile(filePath);
    if (!jsonFile.is_open())
    {
        std::cerr << "BIOS config file does not exist, FILE="
                  << filePath.c_str() << "\n";
        rc = -1;
    }
    else
    {
        fileData = Json::parse(jsonFile, nullptr, false);
        if (fileData.is_discarded())
        {
            std::cerr << "Parsing config file failed, FILE=" << filePath.c_str()
                      << "\n";
            rc = -1;
        }
    }

    return rc;
}

namespace bios_enum
{

namespace internal
{

using Value = std::string;

/** @brief Map of DBus property value to attribute value
 */
using DbusValToValMap = std::map<PropertyValue, Value>;

/** @brief Map containing the DBus property value to attribute value map for the
 * BIOS enumeration type attributes
 */
std::map<AttrName, DbusValToValMap> dbusValToValMaps;

/** @brief Map containing the possible and the default values for the BIOS
 *         enumeration type attributes.
 */
AttrValuesMap valueMap;

/** @brief Populate the mapping between D-Bus property value and attribute value
 *         for the BIOS enumeration attribute.
 *
 *  @param[in] type - type of the D-Bus property
 *  @param[in] dBusValues - json array of D-Bus property values
 *  @param[in] pv - Possible values for the BIOS enumeration attribute
 *
 */
DbusValToValMap populateMapping(const std::string& type, const Json& dBusValues,
                                const PossibleValues& pv)
{
    size_t pos = 0;
    PropertyValue value;
    DbusValToValMap valueMap;
    for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos)
    {
        if (type == "uint8_t")
        {
            value = static_cast<uint8_t>(it.value());
        }
        else if (type == "uint16_t")
        {
            value = static_cast<uint16_t>(it.value());
        }
        else if (type == "uint32_t")
        {
            value = static_cast<uint32_t>(it.value());
        }
        else if (type == "uint64_t")
        {
            value = static_cast<uint64_t>(it.value());
        }
        else if (type == "int16_t")
        {
            value = static_cast<int16_t>(it.value());
        }
        else if (type == "int32_t")
        {
            value = static_cast<int32_t>(it.value());
        }
        else if (type == "int64_t")
        {
            value = static_cast<int64_t>(it.value());
        }
        else if (type == "bool")
        {
            value = static_cast<bool>(it.value());
        }
        else if (type == "double")
        {
            value = static_cast<double>(it.value());
        }
        else if (type == "string")
        {
            value = static_cast<std::string>(it.value());
        }
        else
        {
            std::cerr << "Unknown D-Bus property type, TYPE=" << type.c_str()
                      << "\n";
        }

        valueMap.emplace(value, pv[pos]);
    }

    return valueMap;
}
} // namespace internal

int setupBIOSStrings(const Json& entry, Strings& strings)
{
    Json pvs = entry.value("possible_values", emptyJsonList);

    for (auto& pv : pvs)
    {
        strings.emplace_back(std::move(pv.get<std::string>()));
    }

    return 0;
}

int setup(const Json& entry)
{
    PossibleValues possibleValues;
    DefaultValues defaultValues;

    std::string attrName = entry.value("attribute_name", "");
    Json pv = entry["possible_values"];
    for (auto& val : pv)
    {
        possibleValues.emplace_back(std::move(val));
    }
    Json dv = entry["default_values"];
    for (auto& val : dv)
    {
        defaultValues.emplace_back(std::move(val));
    }
    if (entry.count("dbus") != 0)
    {
        auto dbusEntry = entry.value("dbus", emptyJson);
        std::string propertyType = dbusEntry.value("property_type", "");
        Json propValues = dbusEntry["property_values"];
        internal::dbusValToValMaps.emplace(
            attrName, internal::populateMapping(propertyType, propValues,
                                                possibleValues));
    }
    // Defaulting all the types of attributes to BIOSEnumeration
    internal::valueMap.emplace(std::move(attrName),
                               std::make_tuple(entry.count("dbus") == 0,
                                               std::move(possibleValues),
                                               std::move(defaultValues)));
    return 0;
}

const AttrValuesMap& getValues()
{
    return internal::valueMap;
}

CurrentValues getAttrValue(const AttrName& attrName)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    CurrentValues currentValues;
    PropertyValue propValue;

    if (dBusMap == std::nullopt)
    {
        const auto& valueEntry = internal::valueMap.at(attrName);
        const auto& [readOnly, possibleValues, currentValues] = valueEntry;
        return currentValues;
    }

    const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
    propValue = pldm::utils::DBusHandler().getDbusPropertyVariant(
        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
        dBusMap->interface.c_str());

    auto iter = dbusValToValMap.find(propValue);
    if (iter != dbusValToValMap.end())
    {
        currentValues.push_back(iter->second);
    }

    return currentValues;
}

int setAttrValue(const AttrName& attrName,
                 const pldm_bios_attr_val_table_entry* attrValueEntry,
                 const pldm_bios_attr_table_entry* attrEntry,
                 const BIOSStringTable& stringTable)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    if (dBusMap == std::nullopt)
    {
        return PLDM_SUCCESS;
    }

    uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
    std::vector<uint16_t> pvHdls(pvNum, 0);
    pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrEntry, pvHdls.data(),
                                                   pvNum);

    uint8_t defNum =
        pldm_bios_table_attr_value_entry_enum_decode_number(attrValueEntry);

    assert(defNum == 1);

    std::vector<uint8_t> currHdls(1, 0);
    pldm_bios_table_attr_value_entry_enum_decode_handles(
        attrValueEntry, currHdls.data(), currHdls.size());

    auto valueString = stringTable.findString(pvHdls[currHdls[0]]);

    const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);

    auto it = std::find_if(dbusValToValMap.begin(), dbusValToValMap.end(),
                           [&valueString](const auto& typePair) {
                               return typePair.second == valueString;
                           });
    if (it == dbusValToValMap.end())
    {
        std::cerr << "Invalid Enum Value\n";
        return PLDM_ERROR;
    }

    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), it->first);

    return PLDM_SUCCESS;
}

} // namespace bios_enum

namespace bios_string
{

/** @brief BIOS string types
 */
enum BIOSStringEncoding
{
    UNKNOWN = 0x00,
    ASCII = 0x01,
    HEX = 0x02,
    UTF_8 = 0x03,
    UTF_16LE = 0x04,
    UTF_16BE = 0x05,
    VENDOR_SPECIFIC = 0xFF
};

const std::map<std::string, uint8_t> strTypeMap{
    {"Unknown", UNKNOWN},
    {"ASCII", ASCII},
    {"Hex", HEX},
    {"UTF-8", UTF_8},
    {"UTF-16LE", UTF_16LE},
    {"UTF-16LE", UTF_16LE},
    {"Vendor Specific", VENDOR_SPECIFIC}};

namespace internal
{

/** @brief Map containing the possible and the default values for the BIOS
 *         string type attributes.
 */
AttrValuesMap valueMap;

} // namespace internal

int setup(const Json& jsonEntry)
{

    std::string attr = jsonEntry.value("attribute_name", "");
    // Transfer string type from string to enum
    std::string strTypeTmp = jsonEntry.value("string_type", "Unknown");
    auto iter = strTypeMap.find(strTypeTmp);
    if (iter == strTypeMap.end())
    {
        std::cerr << "Wrong string type, STRING_TYPE=" << strTypeTmp.c_str()
                  << " ATTRIBUTE_NAME=" << attr.c_str() << "\n";
        return -1;
    }
    uint8_t strType = iter->second;

    uint16_t minStrLen = jsonEntry.value("minimum_string_length", 0);
    uint16_t maxStrLen = jsonEntry.value("maximum_string_length", 0);
    uint16_t defaultStrLen = jsonEntry.value("default_string_length", 0);
    std::string defaultStr = jsonEntry.value("default_string", "");

    pldm_bios_table_attr_entry_string_info info = {
        0,     /* name handle */
        false, /* read only */
        strType, minStrLen, maxStrLen, defaultStrLen, defaultStr.data(),
    };

    const char* errmsg;
    auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
    if (rc != PLDM_SUCCESS)
    {
        std::cerr << "Wrong filed for string attribute, ATTRIBUTE_NAME="
                  << attr.c_str() << " ERRMSG=" << errmsg
                  << " MINIMUM_STRING_LENGTH=" << minStrLen
                  << " MAXIMUM_STRING_LENGTH=" << maxStrLen
                  << " DEFAULT_STRING_LENGTH=" << defaultStrLen
                  << " DEFAULT_STRING=" << defaultStr.data() << "\n";
        return -1;
    }

    // Defaulting all the types of attributes to BIOSString
    internal::valueMap.emplace(
        std::move(attr),
        std::make_tuple(jsonEntry.count("dbus") == 0, strType, minStrLen,
                        maxStrLen, defaultStrLen, std::move(defaultStr)));

    return 0;
}

const AttrValuesMap& getValues()
{
    return internal::valueMap;
}

std::string getAttrValue(const AttrName& attrName)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    std::variant<std::string> propValue;

    if (dBusMap == std::nullopt)
    { // return default string
        const auto& valueEntry = internal::valueMap.at(attrName);
        return std::get<DefaultStr>(valueEntry);
    }

    return pldm::utils::DBusHandler().getDbusProperty<std::string>(
        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
        dBusMap->interface.c_str());
}

std::string stringToUtf8(BIOSStringEncoding stringType,
                         const std::vector<uint8_t>& data)
{
    switch (stringType)
    {
        case ASCII:
        case UTF_8:
        case HEX:
            return std::string(data.begin(), data.end());
        case UTF_16BE:
        case UTF_16LE: // TODO
            return std::string(data.begin(), data.end());
        case VENDOR_SPECIFIC:
            throw std::invalid_argument("Vendor Specific is unsupported");
        case UNKNOWN:
            throw std::invalid_argument("Unknown String Type");
    }
    throw std::invalid_argument("String Type Error");
}

int setAttrValue(const AttrName& attrName,
                 const pldm_bios_attr_val_table_entry* attrValueEntry,
                 const pldm_bios_attr_table_entry* attrEntry,
                 const BIOSStringTable&)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    if (dBusMap == std::nullopt)
    {
        return PLDM_SUCCESS;
    }

    auto stringType =
        pldm_bios_table_attr_entry_string_decode_string_type(attrEntry);

    variable_field currentString{};
    pldm_bios_table_attr_value_entry_string_decode_string(attrValueEntry,
                                                          &currentString);
    std::vector<uint8_t> data(currentString.ptr,
                              currentString.ptr + currentString.length);

    PropertyValue value =
        stringToUtf8(static_cast<BIOSStringEncoding>(stringType), data);
    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);

    return PLDM_SUCCESS;
}

} // namespace bios_string

namespace bios_integer
{

AttrValuesMap valueMap;

int setup(const Json& jsonEntry)
{

    std::string attr = jsonEntry.value("attribute_name", "");
    // Transfer string type from string to enum

    uint64_t lowerBound = jsonEntry.value("lower_bound", 0);
    uint64_t upperBound = jsonEntry.value("upper_bound", 0);
    uint32_t scalarIncrement = jsonEntry.value("scalar_increment", 1);
    uint64_t defaultValue = jsonEntry.value("default_value", 0);
    pldm_bios_table_attr_entry_integer_info info = {
        0,     /* name handle*/
        false, /* read only */
        lowerBound, upperBound, scalarIncrement, defaultValue,
    };
    const char* errmsg = nullptr;
    auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
    if (rc != PLDM_SUCCESS)
    {
        std::cerr << "Wrong filed for integer attribute, ATTRIBUTE_NAME="
                  << attr.c_str() << " ERRMSG=" << errmsg
                  << " LOWER_BOUND=" << lowerBound
                  << " UPPER_BOUND=" << upperBound
                  << " DEFAULT_VALUE=" << defaultValue
                  << " SCALAR_INCREMENT=" << scalarIncrement << "\n";
        return -1;
    }

    valueMap.emplace(std::move(attr),
                     std::make_tuple(jsonEntry.count("dbus") == 0, lowerBound,
                                     upperBound, scalarIncrement,
                                     defaultValue));

    return 0;
}

const AttrValuesMap& getValues()
{
    return valueMap;
}

uint64_t getAttrValue(const AttrName& attrName)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    std::variant<std::string> propValue;

    if (dBusMap == std::nullopt)
    { // return default string
        const auto& valueEntry = valueMap.at(attrName);
        return std::get<AttrDefaultValue>(valueEntry);
    }

    return pldm::utils::DBusHandler().getDbusProperty<uint64_t>(
        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
        dBusMap->interface.c_str());
}

int setAttrValue(const AttrName& attrName,
                 const pldm_bios_attr_val_table_entry* attrValueEntry,
                 const pldm_bios_attr_table_entry*, const BIOSStringTable&)
{
    const auto& dBusMap = BIOSAttrLookup.at(attrName);
    if (dBusMap == std::nullopt)
    {
        return PLDM_SUCCESS;
    }

    uint64_t currentValue =
        pldm_bios_table_attr_value_entry_integer_decode_cv(attrValueEntry);

    PropertyValue value = static_cast<uint64_t>(currentValue);
    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);

    return PLDM_SUCCESS;
}

} // namespace bios_integer

const std::map<BIOSJsonName, BIOSStringHandler> BIOSStringHandlers = {
    {bIOSEnumJson, bios_enum::setupBIOSStrings},
};

const std::map<BIOSJsonName, typeHandler> BIOSTypeHandlers = {
    {bIOSEnumJson, bios_enum::setup},
    {bIOSStrJson, bios_string::setup},
    {bIOSIntegerJson, bios_integer::setup},
};

void setupBIOSStrings(const BIOSJsonName& jsonName, const Json& entry,
                      Strings& strings)
{
    strings.emplace_back(entry.value("attribute_name", ""));
    auto iter = BIOSStringHandlers.find(jsonName);
    if (iter != BIOSStringHandlers.end())
    {
        iter->second(entry, strings);
    }
}

void setupBIOSAttrLookup(const Json& jsonEntry, AttrLookup& lookup)
{
    std::optional<DBusMapping> dBusMap;
    std::string attrName = jsonEntry.value("attribute_name", "");

    if (jsonEntry.count("dbus") != 0)
    {
        auto dBusEntry = jsonEntry.value("dbus", emptyJson);
        std::string objectPath = dBusEntry.value("object_path", "");
        std::string interface = dBusEntry.value("interface", "");
        std::string propertyName = dBusEntry.value("property_name", "");
        std::string propertyType = dBusEntry.value("property_type", "");
        if (!objectPath.empty() && !interface.empty() &&
            !propertyName.empty() &&
            (SupportedDbusPropertyTypes.find(propertyType) !=
             SupportedDbusPropertyTypes.end()))
        {
            dBusMap = std::optional<DBusMapping>(
                {objectPath, interface, propertyName, propertyType});
        }
        else
        {
            std::cerr << "Invalid dbus config, OBJPATH="
                      << dBusMap->objectPath.c_str()
                      << " INTERFACE=" << dBusMap->interface.c_str()
                      << " PROPERTY_NAME=" << dBusMap->propertyName.c_str()
                      << " PROPERTY_TYPE=" << dBusMap->propertyType.c_str()
                      << "\n";
        }
    }
    lookup.emplace(attrName, dBusMap);
}

int setupBIOSType(const BIOSJsonName& jsonName, const Json& entry)
{
    auto iter = BIOSTypeHandlers.find(jsonName);
    if (iter != BIOSTypeHandlers.end())
    {
        iter->second(entry);
    }
    return 0;
}

const std::vector<BIOSJsonName> BIOSConfigFiles = {bIOSEnumJson, bIOSStrJson,
                                                   bIOSIntegerJson};

int setupConfig(const char* dirPath)
{
    if (!BIOSStrings.empty() && !BIOSAttrLookup.empty())
    {
        return 0;
    }

    fs::path dir(dirPath);
    if (!fs::exists(dir) || fs::is_empty(dir))
    {
        std::cerr << "BIOS config directory does not exist or empty, DIR="
                  << dirPath << "\n";
        return -1;
    }
    for (auto jsonName : BIOSConfigFiles)
    {
        Json json;
        if (parseBIOSJsonFile(dir, jsonName, json) < 0)
        {
            continue;
        }
        auto entries = json.value("entries", emptyJsonList);
        for (auto& entry : entries)
        {
            setupBIOSStrings(jsonName, entry, BIOSStrings);
            setupBIOSAttrLookup(entry, BIOSAttrLookup);
            setupBIOSType(jsonName, entry);
        }
    }
    if (BIOSStrings.empty())
    { // means there is no attribute
        std::cerr << "No attribute is found in the config directory, DIR="
                  << dirPath << "\n";
        return -1;
    }
    return 0;
}

using setAttrValueHandler = std::function<int(
    const AttrName&, const pldm_bios_attr_val_table_entry*,
    const pldm_bios_attr_table_entry*, const BIOSStringTable&)>;

const std::map<AttrType, setAttrValueHandler> SetAttrValueMap{{
    {PLDM_BIOS_STRING, bios_string::setAttrValue},
    {PLDM_BIOS_STRING_READ_ONLY, bios_string::setAttrValue},
    {PLDM_BIOS_ENUMERATION, bios_enum::setAttrValue},
    {PLDM_BIOS_ENUMERATION_READ_ONLY, bios_enum::setAttrValue},
    {PLDM_BIOS_INTEGER, bios_integer::setAttrValue},
    {PLDM_BIOS_INTEGER_READ_ONLY, bios_integer::setAttrValue},

}};

int setAttributeValueOnDbus(const variable_field* attributeData,
                            const BIOSTable& biosAttributeTable,
                            const BIOSStringTable& stringTable)
{
    Table attributeTable;
    biosAttributeTable.load(attributeTable);
    auto attrValueEntry =
        reinterpret_cast<const pldm_bios_attr_val_table_entry*>(
            attributeData->ptr);

    auto attrType =
        pldm_bios_table_attr_value_entry_decode_attribute_type(attrValueEntry);
    auto attrHandle = pldm_bios_table_attr_value_entry_decode_attribute_handle(
        attrValueEntry);

    auto attrEntry = pldm_bios_table_attr_find_by_handle(
        attributeTable.data(), attributeTable.size(), attrHandle);

    assert(attrEntry != nullptr);

    auto attrNameHandle =
        pldm_bios_table_attr_entry_decode_string_handle(attrEntry);

    auto attrName = stringTable.findString(attrNameHandle);

    try
    {
        auto rc = SetAttrValueMap.at(attrType)(attrName, attrValueEntry,
                                               attrEntry, stringTable);
        return rc;
    }
    catch (const std::exception& e)
    {
        std::cerr << "setAttributeValueOnDbus Error: " << e.what() << std::endl;
        return PLDM_ERROR;
    }
}

} // namespace bios_parser
