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

#include <libphal.H>

#include <phosphor-logging/lg2.hpp>
#include <watchdog_common.hpp>
#include <watchdog_dbus.hpp>
#include <watchdog_handler.hpp>
#include <watchdog_logging.hpp>

namespace watchdog
{
namespace dump
{

void triggerHostbootDump(const uint32_t timeout)
{
    constexpr auto HOST_STATE_DIAGNOSTIC_MODE =
        "obmc-host-diagnostic-mode@0.target";
    constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";

    // Put system into diagnostic mode
    transitionHost(HOST_STATE_DIAGNOSTIC_MODE);

    eventWatchdogTimeout(timeout);

    // Put system into quiesce state
    transitionHost(HOST_STATE_QUIESCE_TGT);
}

/**
 * @brief get SBE special callout information
 *
 * @details This function adds the special sbe callout in the user provided
 * json callout list. includes BMC0002 procedure callout with high priority
 * and processor callout with medium priority.
 *
 * @param[in] procTarget - pdbg processor target
 * @param[out] jsonCalloutDataList - reference to json callout list
 */
static void getSBECallout(struct pdbg_target* procTarget,
                          json& jsonCalloutDataList)
{
    using namespace openpower::phal::pdbg;
    json jsonProcedCallout;

    // Add procedure callout
    jsonProcedCallout["Procedure"] = "BMC0002";
    jsonProcedCallout["Priority"] = "H";
    jsonCalloutDataList.emplace_back(jsonProcedCallout);
    try
    {
        ATTR_LOCATION_CODE_Type locationCode;
        // Initialize with default data.
        memset(&locationCode, '\0', sizeof(locationCode));
        // Get location code information
        openpower::phal::pdbg::getLocationCode(procTarget, locationCode);
        json jsonProcCallout;
        jsonProcCallout["LocationCode"] = locationCode;
        jsonProcCallout["Deconfigured"] = false;
        jsonProcCallout["Guarded"] = false;
        jsonProcCallout["Priority"] = "M";
        jsonCalloutDataList.emplace_back(jsonProcCallout);
    }
    catch (const std::exception& e)
    {
        lg2::error("getLocationCode({LOCATION}): Exception({ERROR})",
                   "LOCATION", pdbg_target_path(procTarget), "ERROR", e);
    }
}

void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout)
{
    using namespace openpower::phal;

    sbeError_t sbeError;
    bool dumpIsRequired = false;

    try
    {
        // Capture FFDC information on primary processor
        sbeError = sbe::captureFFDC(procTarget);
    }
    catch (const std::exception& e)
    {
        // Failed to collect FFDC information
        lg2::error("captureFFDC: Exception{ERROR}", "ERROR", e);
        dumpIsRequired = true;
    }

    // event type
    std::string event;
    if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) ||
        (sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired))
    {
        lg2::info("No FFDC data");
        event = "org.open_power.Processor.Error.SbeBootTimeout";
        dumpIsRequired = true;
    }
    else
    {
        lg2::error("SBE Boot failure");
        event = "org.open_power.Processor.Error.SbeBootFailure";
    }

    // Additional data
    std::map<std::string, std::string> additionalData;

    // SRC6 : [0:15] chip position
    uint32_t index = pdbg_target_index(procTarget);
    additionalData.emplace("SRC6", std::to_string(index << 16));
    additionalData.emplace("SBE_ERR_MSG", sbeError.what());

    // FFDC
    auto ffdc = std::vector<FFDCTuple>{};
    // get SBE ffdc file descriptor
    auto fd = sbeError.getFd();

    // Log error with additional ffdc if fd is valid
    if (fd > 0)
    {
        ffdc.push_back(
            std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
                                Create::FFDCFormat::Custom,
                            static_cast<uint8_t>(0xCB),
                            static_cast<uint8_t>(0x01), sbeError.getFd()));
    }

    std::unique_ptr<FFDCFile> ffdcFilePtr;
    try
    {
        if (dumpIsRequired)
        {
            // Additional callout is required for SBE timeout case
            // In this case no SBE FFDC information available and
            // required to add default callouts.
            json jsonCalloutDataList;
            jsonCalloutDataList = json::array();
            getSBECallout(procTarget, jsonCalloutDataList);
            ffdcFilePtr = std::make_unique<FFDCFile>(jsonCalloutDataList);
            ffdc.push_back(std::make_tuple(
                sdbusplus::xyz::openbmc_project::Logging::server::Create::
                    FFDCFormat::JSON,
                static_cast<uint8_t>(0xCA), static_cast<uint8_t>(0x01),
                ffdcFilePtr->getFileDescriptor()));
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("Skipping SBE special callout due to Exception({ERROR})",
                   "ERROR", e);
    }
    auto pelId = createPel(event, additionalData, ffdc);

    if (dumpIsRequired)
    {
        try
        {
            using namespace openpower::phal;

            // Check SBE dump collection allowed
            bool dumpAllowed = sbe::isDumpAllowed(procTarget);
            if (!dumpAllowed)
            {
                // Possibly another collection in progress, skip dump collection
                lg2::error("Another collection is in progress, skipping "
                           "dump collection");
                return;
            }
        }
        catch (const std::exception& e)
        {
            lg2::error("Exception {ERROR} occurred", "ERROR", e);
            return;
        }

        DumpParameters dumpParameters;
        dumpParameters.logId = pelId;
        dumpParameters.unitId = index;
        dumpParameters.timeout = timeout;
        dumpParameters.dumpType = DumpType::SBE;

        // will not return until dump is complete or timeout
        requestDump(dumpParameters);
    }
}

} // namespace dump
} // namespace watchdog
