#include "bios_parser.hpp"

#include "libpldmresponder/utils.hpp"

#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <optional>
#include <phosphor-logging/log.hpp>

namespace bios_parser
{

using Json = nlohmann::json;
namespace fs = std::filesystem;
using namespace phosphor::logging;

namespace
{

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

} // namespace

int parseBiosJsonFile(const char* dirPath, const std::string& fileName,
                      Json& fileData)
{
    int rc = 0;

    fs::path filePath(dirPath);
    filePath /= fileName;

    std::ifstream jsonFile(filePath);
    if (!jsonFile.is_open())
    {
        log<level::ERR>("BIOS config file does not exist",
                        entry("FILE=%s", filePath.c_str()));
        rc = -1;
    }
    else
    {
        fileData = Json::parse(jsonFile, nullptr, false);
        if (fileData.is_discarded())
        {
            log<level::ERR>("Parsing config file failed",
                            entry("FILE=%s", filePath.c_str()));
            rc = -1;
        }
    }

    return rc;
}

namespace bios_enum
{

namespace internal
{

using PropertyValue =
    std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
                 uint64_t, double, std::string>;
using Value = std::string;

/** @struct DBusMapping
 *
 *  Data structure for storing information regarding BIOS enumeration attribute
 *  and the D-Bus object for the attribute.
 */
struct DBusMapping
{
    std::string objectPath;   //!< D-Bus object path
    std::string interface;    //!< D-Bus interface
    std::string propertyName; //!< D-Bus property name
    std::map<PropertyValue, Value>
        dBusValToValMap; //!< Map of D-Bus property
                         //!< value to attribute value
};

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

/** @brief Map containing the optional D-Bus property information about the
 *         BIOS enumeration type attributes.
 */
std::map<AttrName, std::optional<DBusMapping>> attrLookup;

/** @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
 *  @param[out] mapping - D-Bus mapping object for the attribute
 *
 */
void populateMapping(const std::string& type, const Json& dBusValues,
                     const PossibleValues& pv, DBusMapping& mapping)
{
    size_t pos = 0;
    PropertyValue value;
    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
        {
            log<level::ERR>("Unknown D-Bus property type",
                            entry("TYPE=%s", type.c_str()));
        }

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

/** @brief Read the possible values for the BIOS enumeration type
 *
 *  @param[in] possibleValues - json array of BIOS enumeration possible values
 */
PossibleValues readPossibleValues(Json& possibleValues)
{
    Strings biosStrings{};

    for (auto& val : possibleValues)
    {
        biosStrings.emplace_back(std::move(val));
    }

    return biosStrings;
}

} // namespace internal

int setupValueLookup(const char* dirPath)
{
    int rc = 0;

    if (!internal::valueMap.empty() && !internal::attrLookup.empty())
    {
        return rc;
    }

    // Parse the BIOS enumeration config file
    fs::path filePath(dirPath);
    filePath /= bIOSEnumJson;

    std::ifstream jsonFile(filePath);
    if (!jsonFile.is_open())
    {
        log<level::ERR>("BIOS enum config file does not exist",
                        entry("FILE=%s", filePath.c_str()));
        rc = -1;
        return rc;
    }

    auto fileData = Json::parse(jsonFile, nullptr, false);
    if (fileData.is_discarded())
    {
        log<level::ERR>("Parsing config file failed");
        rc = -1;
        return rc;
    }

    auto entries = fileData.value("entries", emptyJsonList);
    // Iterate through each JSON object in the config file
    for (const auto& entry : entries)
    {
        std::string attr = entry.value("attribute_name", "");
        PossibleValues possibleValues;
        DefaultValues defaultValues;

        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));
        }

        std::optional<internal::DBusMapping> dBusMap = std::nullopt;

        if (entry.count("dbus") != 0)
        {
            auto dBusEntry = entry.value("dbus", emptyJson);
            dBusMap = std::make_optional<internal::DBusMapping>();
            dBusMap.value().objectPath = dBusEntry.value("object_path", "");
            dBusMap.value().interface = dBusEntry.value("interface", "");
            dBusMap.value().propertyName = dBusEntry.value("property_name", "");
            std::string propType = dBusEntry.value("property_type", "");
            Json propValues = dBusEntry["property_values"];
            internal::populateMapping(propType, propValues, possibleValues,
                                      dBusMap.value());
        }

        internal::attrLookup.emplace(attr, std::move(dBusMap));

        // Defaulting all the types of attributes to BIOSEnumeration
        internal::valueMap.emplace(
            std::move(attr), std::make_tuple(false, std::move(possibleValues),
                                             std::move(defaultValues)));
    }

    return rc;
}

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

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

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

    auto bus = sdbusplus::bus::new_default();
    auto service = pldm::responder::getService(bus, dBusMap.value().objectPath,
                                               dBusMap.value().interface);
    auto method =
        bus.new_method_call(service.c_str(), dBusMap.value().objectPath.c_str(),
                            "org.freedesktop.DBus.Properties", "Get");
    method.append(dBusMap.value().interface, dBusMap.value().propertyName);
    auto reply = bus.call(method);
    reply.read(propValue);

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

    return currentValues;
}

} // 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
{

/** @struct DBusMapping
 *
 *  Data structure for storing information regarding BIOS string attribute
 *  and the D-Bus object for the attribute.
 */
struct DBusMapping
{
    std::string objectPath;   //!< D-Bus object path
    std::string interface;    //!< D-Bus interface
    std::string propertyName; //!< D-Bus property name
};

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

/** @brief Map containing the optional D-Bus property information about the
 *         BIOS string type attributes.
 */
std::map<AttrName, std::optional<DBusMapping>> attrLookup;

} // namespace internal

int setupValueLookup(const char* dirPath)
{
    int rc = 0;

    if (!internal::valueMap.empty() && !internal::attrLookup.empty())
    {
        return rc;
    }

    Json fileData;
    rc = parseBiosJsonFile(dirPath, bIOSStrJson, fileData);
    if (rc != 0)
    {
        return rc;
    }

    auto entries = fileData.value("entries", emptyJsonList);
    // Iterate through each JSON object in the config file
    for (const auto& entry : entries)
    {
        std::string attr = entry.value("attribute_name", "");
        // Transfer string type from string to enum
        std::string strTypeTmp = entry.value("string_type", "Unknown");
        auto iter = strTypeMap.find(strTypeTmp);
        if (iter == strTypeMap.end())
        {
            log<level::ERR>(
                "Wrong string type",
                phosphor::logging::entry("STRING_TYPE=%s", strTypeTmp.c_str()),
                phosphor::logging::entry("ATTRIBUTE_NAME=%s", attr.c_str()));
            return -1;
        }
        uint8_t strType = iter->second;

        uint16_t minStrLen = entry.value("minimum_string_length", 0);
        uint16_t maxStrLen = entry.value("maximum_string_length", 0);
        if (maxStrLen - minStrLen < 0)
        {
            log<level::ERR>(
                "Maximum string length is smaller than minimum string length",
                phosphor::logging::entry("ATTRIBUTE_NAME=%s", attr.c_str()));
            return -1;
        }
        uint16_t defaultStrLen = entry.value("default_string_length", 0);
        std::string defaultStr = entry.value("default_string", "");
        if ((defaultStrLen == 0) && (defaultStr.size() > 0))
        {
            log<level::ERR>(
                "Default string length is 0, but default string is existing",
                phosphor::logging::entry("ATTRIBUTE_NAME=%s", attr.c_str()));
            return -1;
        }

        // dbus handling
        std::optional<internal::DBusMapping> dBusMap;

        if (entry.count("dbus") != 0)
        {
            auto dBusEntry = entry.value("dbus", emptyJson);
            dBusMap = std::make_optional<internal::DBusMapping>();
            dBusMap->objectPath = dBusEntry.value("object_path", "");
            dBusMap->interface = dBusEntry.value("interface", "");
            dBusMap->propertyName = dBusEntry.value("property_name", "");
            if (dBusMap->objectPath.empty() || dBusMap->interface.empty() ||
                dBusMap->propertyName.empty())
            {
                log<level::ERR>(
                    "Invalid dbus config",
                    phosphor::logging::entry("OBJPATH=%s",
                                             dBusMap->objectPath.c_str()),
                    phosphor::logging::entry("INTERFACE=%s",
                                             dBusMap->interface.c_str()),
                    phosphor::logging::entry("PROPERTY_NAME=%s",
                                             dBusMap->propertyName.c_str()));
                return -1;
            }
        }

        internal::attrLookup.emplace(attr, std::move(dBusMap));

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

    return rc;
}

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

std::string getAttrValue(const AttrName& attrName)
{
    const auto& dBusMap = internal::attrLookup.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);
    }

    auto bus = sdbusplus::bus::new_default();
    auto service = pldm::responder::getService(bus, dBusMap->objectPath,
                                               dBusMap->interface);
    auto method =
        bus.new_method_call(service.c_str(), dBusMap->objectPath.c_str(),
                            "org.freedesktop.DBus.Properties", "Get");
    method.append(dBusMap->interface, dBusMap->propertyName);
    auto reply = bus.call(method);
    reply.read(propValue);

    return std::get<std::string>(propValue);
}

} // namespace bios_string

Strings getStrings(const char* dirPath)
{
    Strings biosStrings{};
    fs::path dir(dirPath);

    if (!fs::exists(dir) || fs::is_empty(dir))
    {
        return biosStrings;
    }

    for (const auto& file : fs::directory_iterator(dir))
    {
        std::ifstream jsonFile(file.path().c_str());
        if (!jsonFile.is_open())
        {
            log<level::ERR>("JSON BIOS config file does not exist",
                            entry("FILE=%s", file.path().filename().c_str()));
            continue;
        }

        auto fileData = Json::parse(jsonFile, nullptr, false);
        if (fileData.is_discarded())
        {
            log<level::ERR>("Parsing config file failed",
                            entry("FILE=%s", file.path().filename().c_str()));
            continue;
        }

        auto entries = fileData.value("entries", emptyJsonList);

        // Iterate through each entry in the config file
        for (auto& entry : entries)
        {
            biosStrings.emplace_back(entry.value("attribute_name", ""));

            // For BIOS enumeration attributes the possible values are strings
            if (file.path().filename() == bIOSEnumJson)
            {
                auto possibleValues = bios_enum::internal::readPossibleValues(
                    entry["possible_values"]);
                std::move(possibleValues.begin(), possibleValues.end(),
                          std::back_inserter(biosStrings));
            }
        }
    }

    return biosStrings;
}

} // namespace bios_parser
