#include "config.h"

#include "bios_handler.hpp"

#include "const.hpp"
#include "ibm_vpd_utils.hpp"
#include "manager.hpp"
#include "types.hpp"

#include <sdbusplus/bus.hpp>

#include <iostream>
#include <memory>
#include <string>
#include <tuple>
#include <variant>

using namespace openpower::vpd;
using namespace openpower::vpd::constants;

namespace openpower
{
namespace vpd
{
namespace manager
{
void BiosHandler::checkAndListenPLDMService()
{
    // Setup a match on NameOwnerChanged to determine when PLDM is up. In
    // the signal handler, call restoreBIOSAttribs
    static std::shared_ptr<sdbusplus::bus::match_t> nameOwnerMatch =
        std::make_shared<sdbusplus::bus::match_t>(
            *conn,
            sdbusplus::bus::match::rules::nameOwnerChanged(
                "xyz.openbmc_project.PLDM"),
            [this](sdbusplus::message_t& msg) {
                if (msg.is_method_error())
                {
                    std::cerr
                        << "Error in reading name owner signal " << std::endl;
                    return;
                }
                std::string name;
                std::string newOwner;
                std::string oldOwner;

                msg.read(name, oldOwner, newOwner);
                if (newOwner != "" && name == "xyz.openbmc_project.PLDM")
                {
                    this->restoreBIOSAttribs();
                    // We don't need the match anymore
                    nameOwnerMatch.reset();
                }
            });
    // Check if PLDM is already running, if it is, we can go ahead and attempt
    // to sync BIOS attributes (since PLDM would have initialized them by the
    // time it acquires a bus name).
    bool isPLDMRunning = false;
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto method =
            bus.new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
                                "org.freedesktop.DBus", "NameHasOwner");
        method.append("xyz.openbmc_project.PLDM");

        auto result = bus.call(method);
        result.read(isPLDMRunning);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cerr << "Failed to check if PLDM is running, assume false"
                  << std::endl;
        std::cerr << e.what() << std::endl;
    }

    std::cout << "Is PLDM running: " << isPLDMRunning << std::endl;

    if (isPLDMRunning)
    {
        nameOwnerMatch.reset();
        restoreBIOSAttribs();
    }
}

void BiosHandler::listenBiosAttribs()
{
    static std::shared_ptr<sdbusplus::bus::match_t> biosMatcher =
        std::make_shared<sdbusplus::bus::match_t>(
            *conn,
            sdbusplus::bus::match::rules::propertiesChanged(
                "/xyz/openbmc_project/bios_config/manager",
                "xyz.openbmc_project.BIOSConfig.Manager"),
            [this](sdbusplus::message_t& msg) { biosAttribsCallback(msg); });
}

void BiosHandler::biosAttribsCallback(sdbusplus::message_t& msg)
{
    if (msg.is_method_error())
    {
        std::cerr << "Error in reading BIOS attribute signal " << std::endl;
        return;
    }
    using BiosProperty = std::tuple<
        std::string, bool, std::string, std::string, std::string,
        std::variant<int64_t, std::string>, std::variant<int64_t, std::string>,
        std::vector<std::tuple<std::string, std::variant<int64_t, std::string>,
                               std::string>>>;

    using BiosBaseTable =
        std::variant<std::monostate, std::map<std::string, BiosProperty>>;
    using BiosBaseTableType = std::map<std::string, BiosBaseTable>;

    std::string object;
    BiosBaseTableType propMap;
    msg.read(object, propMap);
    for (auto prop : propMap)
    {
        if (prop.first == "BaseBIOSTable")
        {
            if (auto list = std::get_if<std::map<std::string, BiosProperty>>(
                    &(prop.second)))
            {
                for (const auto& item : *list)
                {
                    std::string attributeName = std::get<0>(item);
                    if (attributeName == "hb_memory_mirror_mode")
                    {
                        auto attrValue = std::get<5>(std::get<1>(item));
                        auto val = std::get_if<std::string>(&attrValue);
                        if (val)
                        {
                            saveAMMToVPD(*val);
                        }
                    }
                    else if (attributeName == "hb_field_core_override")
                    {
                        auto attrValue = std::get<5>(std::get<1>(item));
                        auto val = std::get_if<int64_t>(&attrValue);
                        if (val)
                        {
                            saveFCOToVPD(*val);
                        }
                    }
                    else if (attributeName == "pvm_keep_and_clear")
                    {
                        auto attrValue = std::get<5>(std::get<1>(item));
                        auto val = std::get_if<std::string>(&attrValue);
                        if (val)
                        {
                            saveKeepAndClearToVPD(*val);
                        }
                    }
                    else if (attributeName == "pvm_create_default_lpar")
                    {
                        auto attrValue = std::get<5>(std::get<1>(item));
                        auto val = std::get_if<std::string>(&attrValue);
                        if (val)
                        {
                            saveCreateDefaultLparToVPD(*val);
                        }
                    }
                    else if (attributeName == "pvm_clear_nvram")
                    {
                        auto attrValue = std::get<5>(std::get<1>(item));
                        auto val = std::get_if<std::string>(&attrValue);
                        if (val)
                        {
                            saveClearNVRAMToVPD(*val);
                        }
                    }
                }
            }
            else
            {
                inventory::PelAdditionalData additionalData;
                additionalData.emplace(
                    "DESCRIPTION",
                    "Invalid type received for BIOS base table property");

                createPEL(additionalData, PelSeverity::ERROR,
                          errIntfForVPDDefault, nullptr);
                std::cerr
                    << "Invalid type received for BIOS base table property"
                    << std::endl;
            }
        }
    }
}

void BiosHandler::saveFCOToVPD(int64_t fcoVal)
{
    if (fcoVal == -1)
    {
        std::cerr << "Invalid FCO value from BIOS: " << fcoVal << std::endl;
        return;
    }

    Binary vpdVal = {0, 0, 0, static_cast<uint8_t>(fcoVal)};
    auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "RG");

    if (valInVPD.size() != 4)
    {
        std::cerr << "Read bad size for VSYS/RG: " << valInVPD.size()
                  << std::endl;
        return;
    }

    if (std::memcmp(vpdVal.data(), valInVPD.data(), 4) != 0)
    {
        std::cout << "Writing FCO to VPD: " << fcoVal << std::endl;
        manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
                             "VSYS", "RG", vpdVal);
    }
}

void BiosHandler::saveAMMToVPD(const std::string& mirrorMode)
{
    Binary vpdVal;
    auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D0");

    if (valInVPD.size() != 1)
    {
        std::cerr << "Read bad size for UTIL/D0: " << valInVPD.size()
                  << std::endl;
        return;
    }

    if (mirrorMode != "Enabled" && mirrorMode != "Disabled")
    {
        std::cerr << "Bad value for Mirror mode BIOS attribute: " << mirrorMode
                  << std::endl;
        return;
    }

    // Write to VPD only if the value is not already what we want to write.
    if (mirrorMode == "Enabled" && valInVPD.at(0) != 2)
    {
        vpdVal.emplace_back(2);
    }
    else if (mirrorMode == "Disabled" && valInVPD.at(0) != 1)
    {
        vpdVal.emplace_back(1);
    }

    if (!vpdVal.empty())
    {
        std::cout << "Writing AMM to VPD: " << static_cast<int>(vpdVal.at(0))
                  << std::endl;
        manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
                             "UTIL", "D0", vpdVal);
    }
}

void BiosHandler::saveKeepAndClearToVPD(const std::string& keepAndClear)
{
    Binary vpdVal;
    auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");

    if (valInVPD.size() != 1)
    {
        std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
                  << std::endl;
        return;
    }

    if (keepAndClear != "Enabled" && keepAndClear != "Disabled")
    {
        std::cerr << "Bad value for keep and clear BIOS attribute: "
                  << keepAndClear << std::endl;
        return;
    }

    // Write to VPD only if the value is not already what we want to write.
    if (keepAndClear == "Enabled" && ((valInVPD.at(0) & 0x01) != 0x01))
    {
        vpdVal.emplace_back(valInVPD.at(0) | 0x01);
    }
    else if (keepAndClear == "Disabled" && ((valInVPD.at(0) & 0x01) != 0))
    {
        vpdVal.emplace_back(valInVPD.at(0) & ~(0x01));
    }

    if (!vpdVal.empty())
    {
        std::cout << "Writing Keep and Clear to VPD: "
                  << static_cast<int>(vpdVal.at(0)) << std::endl;
        manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
                             "UTIL", "D1", vpdVal);
    }
}

void BiosHandler::saveCreateDefaultLparToVPD(
    const std::string& createDefaultLpar)
{
    Binary vpdVal;
    auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");

    if (valInVPD.size() != 1)
    {
        std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
                  << std::endl;
        return;
    }

    if (createDefaultLpar != "Enabled" && createDefaultLpar != "Disabled")
    {
        std::cerr << "Bad value for create default lpar BIOS attribute: "
                  << createDefaultLpar << std::endl;
        return;
    }

    // Write to VPD only if the value is not already what we want to write.
    if (createDefaultLpar == "Enabled" && ((valInVPD.at(0) & 0x02) != 0x02))
    {
        vpdVal.emplace_back(valInVPD.at(0) | 0x02);
    }
    else if (createDefaultLpar == "Disabled" && ((valInVPD.at(0) & 0x02) != 0))
    {
        vpdVal.emplace_back(valInVPD.at(0) & ~(0x02));
    }

    if (!vpdVal.empty())
    {
        std::cout << "Writing create default lpar to VPD: "
                  << static_cast<int>(vpdVal.at(0)) << std::endl;
        manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
                             "UTIL", "D1", vpdVal);
    }
}

void BiosHandler::saveClearNVRAMToVPD(const std::string& clearNVRAM)
{
    Binary vpdVal;
    auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");

    if (valInVPD.size() != 1)
    {
        std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
                  << std::endl;
        return;
    }

    if (clearNVRAM != "Enabled" && clearNVRAM != "Disabled")
    {
        std::cerr << "Bad value for clear NVRAM BIOS attribute: " << clearNVRAM
                  << std::endl;
        return;
    }

    // Write to VPD only if the value is not already what we want to write.
    if (clearNVRAM == "Enabled" && ((valInVPD.at(0) & 0x04) != 0x04))
    {
        vpdVal.emplace_back(valInVPD.at(0) | 0x04);
    }
    else if (clearNVRAM == "Disabled" && ((valInVPD.at(0) & 0x04) != 0))
    {
        vpdVal.emplace_back(valInVPD.at(0) & ~(0x04));
    }

    if (!vpdVal.empty())
    {
        std::cout << "Writing clear NVRAM to VPD: "
                  << static_cast<int>(vpdVal.at(0)) << std::endl;
        manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
                             "UTIL", "D1", vpdVal);
    }
}

int64_t BiosHandler::readBIOSFCO()
{
    int64_t fcoVal = -1;
    auto val = readBIOSAttribute("hb_field_core_override");

    if (auto pVal = std::get_if<int64_t>(&val))
    {
        fcoVal = *pVal;
    }
    else
    {
        std::cerr << "FCO is not an int" << std::endl;
    }
    return fcoVal;
}

std::string BiosHandler::readBIOSAMM()
{
    std::string ammVal{};
    auto val = readBIOSAttribute("hb_memory_mirror_mode");

    if (auto pVal = std::get_if<std::string>(&val))
    {
        ammVal = *pVal;
    }
    else
    {
        std::cerr << "AMM is not a string" << std::endl;
    }
    return ammVal;
}

std::string BiosHandler::readBIOSKeepAndClear()
{
    std::string keepAndClear{};
    auto val = readBIOSAttribute("pvm_keep_and_clear");

    if (auto pVal = std::get_if<std::string>(&val))
    {
        keepAndClear = *pVal;
    }
    else
    {
        std::cerr << "Keep and clear is not a string" << std::endl;
    }
    return keepAndClear;
}

std::string BiosHandler::readBIOSCreateDefaultLpar()
{
    std::string createDefaultLpar{};
    auto val = readBIOSAttribute("pvm_create_default_lpar");

    if (auto pVal = std::get_if<std::string>(&val))
    {
        createDefaultLpar = *pVal;
    }
    else
    {
        std::cerr << "Create default LPAR is not a string" << std::endl;
    }
    return createDefaultLpar;
}

std::string BiosHandler::readBIOSClearNVRAM()
{
    std::string clearNVRAM{};
    auto val = readBIOSAttribute("pvm_clear_nvram");

    if (auto pVal = std::get_if<std::string>(&val))
    {
        clearNVRAM = *pVal;
    }
    else
    {
        std::cerr << "Clear NVRAM is not a string" << std::endl;
    }
    return clearNVRAM;
}

void BiosHandler::saveFCOToBIOS(const std::string& fcoVal, int64_t fcoInBIOS)
{
    if (fcoVal.size() != 4)
    {
        std::cerr << "Bad size for FCO in VPD: " << fcoVal.size() << std::endl;
        return;
    }

    // Need to write?
    if (fcoInBIOS == static_cast<int64_t>(fcoVal.at(3)))
    {
        std::cout << "Skip FCO BIOS write, value is already: " << fcoInBIOS
                  << std::endl;
        return;
    }

    PendingBIOSAttrsType biosAttrs;
    biosAttrs.push_back(
        std::make_pair("hb_field_core_override",
                       std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
                                       "AttributeType.Integer",
                                       fcoVal.at(3))));

    std::cout << "Set hb_field_core_override to: "
              << static_cast<int>(fcoVal.at(3)) << std::endl;

    setBusProperty<PendingBIOSAttrsType>(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
        biosAttrs);
}

void BiosHandler::saveAMMToBIOS(const std::string& ammVal,
                                const std::string& ammInBIOS)
{
    if (ammVal.size() != 1)
    {
        std::cerr << "Bad size for AMM in VPD: " << ammVal.size() << std::endl;
        return;
    }

    // Make sure data in VPD is sane
    if (ammVal.at(0) != 1 && ammVal.at(0) != 2)
    {
        std::cerr << "Bad value for AMM read from VPD: "
                  << static_cast<int>(ammVal.at(0)) << std::endl;
        return;
    }

    // Need to write?
    std::string toWrite = (ammVal.at(0) == 2) ? "Enabled" : "Disabled";
    if (ammInBIOS == toWrite)
    {
        std::cout << "Skip AMM BIOS write, value is already: " << toWrite
                  << std::endl;
        return;
    }

    PendingBIOSAttrsType biosAttrs;
    biosAttrs.push_back(
        std::make_pair("hb_memory_mirror_mode",
                       std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
                                       "AttributeType.Enumeration",
                                       toWrite)));

    std::cout << "Set hb_memory_mirror_mode to: " << toWrite << std::endl;

    setBusProperty<PendingBIOSAttrsType>(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
        biosAttrs);
}

void BiosHandler::saveKeepAndClearToBIOS(const std::string& keepAndClear,
                                         const std::string& keepAndClearInBIOS)
{
    if (keepAndClear.size() != 1)
    {
        std::cerr << "Bad size for Keep and Clear in VPD: "
                  << keepAndClear.size() << std::endl;
        return;
    }

    // Need to write?
    std::string toWrite = (keepAndClear.at(0) & 0x01) ? "Enabled" : "Disabled";
    if (keepAndClearInBIOS == toWrite)
    {
        std::cout << "Skip Keep and Clear BIOS write, value is already: "
                  << toWrite << std::endl;
        return;
    }

    PendingBIOSAttrsType biosAttrs;
    biosAttrs.push_back(
        std::make_pair("pvm_keep_and_clear",
                       std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
                                       "AttributeType.Enumeration",
                                       toWrite)));

    std::cout << "Set pvm_keep_and_clear to: " << toWrite << std::endl;

    setBusProperty<PendingBIOSAttrsType>(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
        biosAttrs);
}

void BiosHandler::saveCreateDefaultLparToBIOS(
    const std::string& createDefaultLpar,
    const std::string& createDefaultLparInBIOS)
{
    if (createDefaultLpar.size() != 1)
    {
        std::cerr << "Bad size for Create default LPAR in VPD: "
                  << createDefaultLpar.size() << std::endl;
        return;
    }

    // Need to write?
    std::string toWrite =
        (createDefaultLpar.at(0) & 0x02) ? "Enabled" : "Disabled";
    if (createDefaultLparInBIOS == toWrite)
    {
        std::cout << "Skip Create default LPAR BIOS write, value is already: "
                  << toWrite << std::endl;
        return;
    }

    PendingBIOSAttrsType biosAttrs;
    biosAttrs.push_back(
        std::make_pair("pvm_create_default_lpar",
                       std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
                                       "AttributeType.Enumeration",
                                       toWrite)));

    std::cout << "Set pvm_create_default_lpar to: " << toWrite << std::endl;

    setBusProperty<PendingBIOSAttrsType>(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
        biosAttrs);
}

void BiosHandler::saveClearNVRAMToBIOS(const std::string& clearNVRAM,
                                       const std::string& clearNVRAMInBIOS)
{
    if (clearNVRAM.size() != 1)
    {
        std::cerr << "Bad size for Clear NVRAM in VPD: " << clearNVRAM.size()
                  << std::endl;
        return;
    }

    // Need to write?
    std::string toWrite = (clearNVRAM.at(0) & 0x04) ? "Enabled" : "Disabled";
    if (clearNVRAMInBIOS == toWrite)
    {
        std::cout << "Skip Clear NVRAM BIOS write, value is already: "
                  << toWrite << std::endl;
        return;
    }

    PendingBIOSAttrsType biosAttrs;
    biosAttrs.push_back(
        std::make_pair("pvm_clear_nvram",
                       std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
                                       "AttributeType.Enumeration",
                                       toWrite)));

    std::cout << "Set pvm_clear_nvram to: " << toWrite << std::endl;

    setBusProperty<PendingBIOSAttrsType>(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
        biosAttrs);
}

void BiosHandler::restoreBIOSAttribs()
{
    // TODO: We could make this slightly more scalable by defining a table of
    // attributes and their corresponding VPD keywords. However, that needs much
    // more thought.
    std::cout << "Attempting BIOS attribute reset" << std::endl;
    // Check if the VPD contains valid data for FCO, AMM, Keep and Clear,
    // Create default LPAR and Clear NVRAM *and* that it differs from the data
    // already in the attributes. If so, set the BIOS attributes as per the
    // value in the VPD. If the VPD contains default data, then initialize the
    // VPD keywords with data taken from the BIOS.
    auto fcoInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "RG");
    auto ammInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D0");
    auto keepAndClearInVPD =
        readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
    auto fcoInBIOS = readBIOSFCO();
    auto ammInBIOS = readBIOSAMM();
    auto keepAndClearInBIOS = readBIOSKeepAndClear();
    auto createDefaultLparInBIOS = readBIOSCreateDefaultLpar();
    auto clearNVRAMInBIOS = readBIOSClearNVRAM();

    if (fcoInVPD == "    ")
    {
        saveFCOToVPD(fcoInBIOS);
    }
    else
    {
        saveFCOToBIOS(fcoInVPD, fcoInBIOS);
    }

    if (ammInVPD.at(0) == 0)
    {
        saveAMMToVPD(ammInBIOS);
    }
    else
    {
        saveAMMToBIOS(ammInVPD, ammInBIOS);
    }

    // No uninitialized handling needed for keep and clear, create default
    // lpar and clear nvram attributes. Their defaults in VPD are 0's which is
    // what we want.
    saveKeepAndClearToBIOS(keepAndClearInVPD, keepAndClearInBIOS);
    // Have to read D1 again because two attributes are stored in the same
    // keyword.
    auto createDefaultLparInVPD =
        readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
    saveCreateDefaultLparToBIOS(createDefaultLparInVPD,
                                createDefaultLparInBIOS);

    auto clearNVRAMInVPD =
        readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
    saveClearNVRAMToBIOS(clearNVRAMInVPD, clearNVRAMInBIOS);

    // Start listener now that we have done the restore
    listenBiosAttribs();
}
} // namespace manager
} // namespace vpd
} // namespace openpower
