#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>>>>;
    using BiosBaseTable = std::variant<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")
        {
            auto list = std::get<0>(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);
                    }
                }
            }
        }
    }
}

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
