extern "C"
{
#include <libpdbg.h>
}

#include "attributes_info.H"

#include "extensions/phal/common_utils.hpp"
#include "extensions/phal/phal_error.hpp"
#include "util.hpp"

#include <fmt/format.h>
#include <libekb.H>

#include <ext_interface.hpp>
#include <phosphor-logging/log.hpp>
#include <registration.hpp>

namespace openpower
{
namespace phal
{

using namespace phosphor::logging;

/**
 *  @brief  Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER
 *          processor position 0/1 depending on boot count before kicking off
 *          the boot.
 *
 *  @return void
 */
void selectBootSeeprom()
{
    struct pdbg_target* procTarget;
    ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect;
    ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect;

    pdbg_for_each_class_target("proc", procTarget)
    {
        if (!isPrimaryProc(procTarget))
        {
            continue;
        }

        // Choose seeprom side to boot from based on boot count
        if (getBootCount() > 0)
        {
            log<level::INFO>("Setting SBE seeprom side to 0",
                             entry("SBE_SIDE_SELECT=%d",
                                   ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY));

            bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY;
            bkpMeaSeePromSelect =
                ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY;
        }
        else
        {
            log<level::INFO>("Setting SBE seeprom side to 1",
                             entry("SBE_SIDE_SELECT=%d",
                                   ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY));
            bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY;
            bkpMeaSeePromSelect =
                ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY;
        }

        // Set the Attribute as per bootcount policy for boot seeprom
        if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget,
                        bkpSeePromSelect))
        {
            log<level::ERR>(
                "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
            throw std::runtime_error(
                "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
        }

        // Set the Attribute as per bootcount policy for measurement seeprom
        if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget,
                        bkpMeaSeePromSelect))
        {
            log<level::ERR>(
                "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
                "failed");
            throw std::runtime_error(
                "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
                "failed");
        }
    }
}

/**
 * @brief Read the HW Level from VPD and set CLK NE termination site
 * Note any failure in this function will result startHost failure.
 */
void setClkNETerminationSite()
{
    // Get Motherborad VINI Recored "HW" keyword
    constexpr auto objPath =
        "/xyz/openbmc_project/inventory/system/chassis/motherboard";
    constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI";
    constexpr auto hwKwd = "HW";

    auto bus = sdbusplus::bus::new_default();

    std::string service = util::getService(bus, objPath, kwdVpdInf);

    auto properties = bus.new_method_call(
        service.c_str(), objPath, "org.freedesktop.DBus.Properties", "Get");
    properties.append(kwdVpdInf);
    properties.append(hwKwd);

    // Store "HW" Keyword data.
    std::variant<std::vector<uint8_t>> val;
    try
    {
        auto result = bus.call(properties);
        result.read(val);
    }
    catch (const sdbusplus::exception::exception& e)
    {
        log<level::ERR>("Get HW Keyword read from VINI Failed");
        throw std::runtime_error("Get HW Keyword read from VINI Failed");
    }

    auto hwData = std::get<std::vector<uint8_t>>(val);

    //"HW" Keyword size is 2 as per VPD spec.
    constexpr auto hwKwdSize = 2;
    if (hwKwdSize != hwData.size())
    {
        log<level::ERR>(
            fmt::format("Incorrect VINI records HW Keyword data size({})",
                        hwData.size())
                .c_str());
        throw std::runtime_error("Incorrect VINI records HW Keyword data size");
    }

    log<level::DEBUG>(fmt::format("VINI Records HW[0]:{} HW[1]:{}",
                                  hwData.at(0), hwData.at(1))
                          .c_str());

    // VINI Record "HW" keyword's Byte 0's MSB bit indicates
    // proc or planar type need to choose.
    constexpr uint8_t SYS_CLK_NE_TERMINATION_ON_MASK = 0x80;

    ATTR_SYS_CLK_NE_TERMINATION_SITE_Type clockTerm =
        ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PLANAR;

    if (SYS_CLK_NE_TERMINATION_ON_MASK & hwData.at(0))
    {
        clockTerm = ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PROC;
    }

    // update all the processor attributes
    struct pdbg_target* procTarget;
    pdbg_for_each_class_target("proc", procTarget)
    {

        if (DT_SET_PROP(ATTR_SYS_CLK_NE_TERMINATION_SITE, procTarget,
                        clockTerm))
        {
            log<level::ERR>(
                "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed");
            throw std::runtime_error(
                "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed");
        }
    }
}

/**
 * @brief Starts the self boot engine on POWER processor position 0
 *        to kick off a boot.
 * @return void
 */
void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL)
{
    try
    {
        phal_init();
        ipl_set_type(iplType);
    }
    catch (std::exception& ex)
    {
        log<level::ERR>("Exception raised during init PHAL",
                        entry("EXCEPTION=%s", ex.what()));
        openpower::pel::detail::processBootError(false);
        throw std::runtime_error("PHAL initialization failed");
    }

    // To clear trace if success
    openpower::pel::detail::processBootError(true);

    setClkNETerminationSite();

    // callback method will be called upon failure which will create the PEL
    int rc = ipl_run_major(0);
    if (rc > 0)
    {
        log<level::ERR>("step 0 failed to start the host");
        throw std::runtime_error("Failed to execute host start boot step");
    }
}

/**
 * @brief Starts the reboot with type memory preserving reboot.
 * @return void
 */
void startHostMpReboot()
{
    // set ipl type as mpipl
    startHost(IPL_TYPE_MPIPL);
}

/**
 * @brief Starts the normal boot type.
 * @return void
 */
void startHostNormal()
{
    // Run select seeprom before poweron
    try
    {
        selectBootSeeprom();

        // To clear trace as it is success
        openpower::pel::detail::processBootError(true);
    }
    catch (const std::exception& ex)
    {
        // create PEL in failure
        openpower::pel::detail::processBootError(false);
        log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what()));
        throw ex;
    }

    startHost();
}

REGISTER_PROCEDURE("startHost", startHostNormal)
REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot)

} // namespace phal
} // namespace openpower
