#include <unistd.h>

#include <analyzer/service_data.hpp>
#include <analyzer/util.hpp>
#include <hei_main.hpp>
#include <phosphor-logging/elog.hpp>
#include <sdbusplus/bus.hpp>
#include <util/bin_stream.hpp>
#include <util/dbus.hpp>
#include <util/ffdc_file.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>
#include <xyz/openbmc_project/Logging/Create/server.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>

#include <fstream>
#include <memory>

namespace LogSvr = sdbusplus::xyz::openbmc_project::Logging::server;

namespace analyzer
{

//------------------------------------------------------------------------------

enum FfdcSubType_t : uint8_t
{
    FFDC_SIGNATURES      = 0x01,
    FFDC_REGISTER_DUMP   = 0x02,
    FFDC_CALLOUT_FFDC    = 0x03,
    FFDC_HB_SCRATCH_REGS = 0x04,

    // For the callout section, the value of '0xCA' is required per the
    // phosphor-logging openpower-pel extention spec.
    FFDC_CALLOUTS = 0xCA,
};

enum FfdcVersion_t : uint8_t
{
    FFDC_VERSION1 = 0x01,
};

//------------------------------------------------------------------------------

void __getSrc(const libhei::Signature& i_signature, uint32_t& o_word6,
              uint32_t& o_word7, uint32_t& o_word8)
{
    o_word6 = o_word7 = o_word8 = 0; // default

    // Note that the chip could be null if there was no root cause attention
    // found during analysis.
    if (nullptr != i_signature.getChip().getChip())
    {
        // [ 0:15] chip model
        // [16:23] reserved space in chip ID
        // [24:31] chip EC level
        o_word6 = i_signature.getChip().getType();

        // [ 0:15] chip position
        // [16:23] node position
        // [24:31] signature attention type
        auto chipPos    = util::pdbg::getChipPos(i_signature.getChip());
        uint8_t nodePos = 0; // TODO: multi-node support
        auto attn       = i_signature.getAttnType();

        o_word7 =
            (chipPos & 0xffff) << 16 | (nodePos & 0xff) << 8 | (attn & 0xff);

        // [ 0:15] signature ID
        // [16:23] signature instance
        // [24:31] signature bit position
        o_word8 = i_signature.toUint32();

        // Word 9 is currently unused
    }
}

//------------------------------------------------------------------------------

void __setSrc(const libhei::Signature& i_rootCause,
              std::map<std::string, std::string>& io_logData)
{
    uint32_t word6 = 0, word7 = 0, word8 = 0;
    __getSrc(i_rootCause, word6, word7, word8);

    io_logData["SRC6"] = std::to_string(word6);
    io_logData["SRC7"] = std::to_string(word7);
    io_logData["SRC8"] = std::to_string(word8);
}

//------------------------------------------------------------------------------

void __addCalloutList(const ServiceData& i_servData,
                      std::vector<util::FFDCFile>& io_userDataFiles)
{
    // Create a new entry for the user data section containing the callout list.
    io_userDataFiles.emplace_back(util::FFDCFormat::JSON, FFDC_CALLOUTS,
                                  FFDC_VERSION1);

    // Use a file stream to write the JSON to file.
    std::ofstream o{io_userDataFiles.back().getPath()};
    o << i_servData.getCalloutList();
}

//------------------------------------------------------------------------------

void __addCalloutFFDC(const ServiceData& i_servData,
                      std::vector<util::FFDCFile>& io_userDataFiles)
{
    // Create a new entry for the user data section containing the FFDC.
    io_userDataFiles.emplace_back(util::FFDCFormat::Custom, FFDC_CALLOUT_FFDC,
                                  FFDC_VERSION1);

    // Use a file stream to write the JSON to file.
    std::ofstream o{io_userDataFiles.back().getPath()};
    o << i_servData.getCalloutFFDC();
}

//------------------------------------------------------------------------------

void __captureSignatureList(const libhei::IsolationData& i_isoData,
                            std::vector<util::FFDCFile>& io_userDataFiles)
{
    // Create a new entry for this user data section regardless if there are any
    // signatures in the list.
    io_userDataFiles.emplace_back(util::FFDCFormat::Custom, FFDC_SIGNATURES,
                                  FFDC_VERSION1);

    // Create a streamer for easy writing to the FFDC file.
    auto path = io_userDataFiles.back().getPath();
    util::BinFileWriter stream{path};

    // The first 4 bytes in the FFDC contains the number of signatures in the
    // list. Then, the list of signatures will follow.

    auto list = i_isoData.getSignatureList();

    uint32_t numSigs = list.size();
    stream << numSigs;

    for (const auto& sig : list)
    {
        // Each signature will use the same format as the SRC (12 bytes each).
        uint32_t word6 = 0, word7 = 0, word8 = 0;
        __getSrc(sig, word6, word7, word8);
        stream << word6 << word7 << word8;
    }

    // If the stream failed for any reason, remove the FFDC file.
    if (!stream.good())
    {
        trace::err("Unable to write signature list FFDC file: %s",
                   path.string().c_str());
        io_userDataFiles.pop_back();
    }
}

//------------------------------------------------------------------------------

void __captureRegisterDump(const libhei::IsolationData& i_isoData,
                           std::vector<util::FFDCFile>& io_userDataFiles)
{
    // Create a new entry for this user data section regardless if there are any
    // registers in the dump.
    io_userDataFiles.emplace_back(util::FFDCFormat::Custom, FFDC_REGISTER_DUMP,
                                  FFDC_VERSION1);

    // Create a streamer for easy writing to the FFDC file.
    auto path = io_userDataFiles.back().getPath();
    util::BinFileWriter stream{path};

    // The first 4 bytes in the FFDC contains the number of chips with register
    // data. Then the data for each chip will follow.

    auto dump = i_isoData.getRegisterDump();

    uint32_t numChips = dump.size();
    stream << numChips;

    for (const auto& entry : dump)
    {
        auto chip    = entry.first;
        auto regList = entry.second;

        // Each chip will have the following information:
        //   4 byte chip model/EC
        //   2 byte chip position
        //   1 byte node position
        //   4 byte number of registers
        // Then the data for each register will follow.

        uint32_t chipType = chip.getType();
        uint16_t chipPos  = util::pdbg::getChipPos(chip);
        uint8_t nodePos   = 0; // TODO: multi-node support
        uint32_t numRegs  = regList.size();
        stream << chipType << chipPos << nodePos << numRegs;

        for (const auto& reg : regList)
        {
            // Each register will have the following information:
            //   3 byte register ID
            //   1 byte register instance
            //   1 byte data size
            //   * byte data buffer (* depends on value of data size)

            libhei::RegisterId_t regId = reg.regId;   // 3 byte
            libhei::Instance_t regInst = reg.regInst; // 1 byte

            auto tmp = libhei::BitString::getMinBytes(reg.data->getBitLen());
            if (255 < tmp)
            {
                trace::inf("Register data execeeded 255 and was truncated: "
                           "regId=0x%06x regInst=%u",
                           regId, regInst);
                tmp = 255;
            }
            uint8_t dataSize = tmp;

            stream << regId << regInst << dataSize;

            stream.write(reg.data->getBufAddr(), dataSize);
        }
    }

    // If the stream failed for any reason, remove the FFDC file.
    if (!stream.good())
    {
        trace::err("Unable to write register dump FFDC file: %s",
                   path.string().c_str());
        io_userDataFiles.pop_back();
    }
}

//------------------------------------------------------------------------------

void __captureHostbootScratchRegisters(
    std::vector<util::FFDCFile>& io_userDataFiles)
{
    // Get the Hostboot scratch registers from the primary processor.

    uint32_t cfamAddr  = 0x283C;
    uint32_t cfamValue = 0;

    uint64_t scomAddr  = 0x4602F489;
    uint64_t scomValue = 0;

    auto priProc = util::pdbg::getPrimaryProcessor();
    if (nullptr == priProc)
    {
        trace::err("Unable to get primary processor");
    }
    else
    {
        if (0 != util::pdbg::getCfam(priProc, cfamAddr, cfamValue))
        {
            cfamValue = 0; // just in case
        }

        if (0 != util::pdbg::getScom(priProc, scomAddr, scomValue))
        {
            scomValue = 0; // just in case
        }
    }

    // Create a new entry for this user data section.
    io_userDataFiles.emplace_back(util::FFDCFormat::Custom,
                                  FFDC_HB_SCRATCH_REGS, FFDC_VERSION1);

    // Create a streamer for easy writing to the FFDC file.
    auto path = io_userDataFiles.back().getPath();
    util::BinFileWriter stream{path};

    // Add the data (CFAM addr/val, then SCOM addr/val).
    stream << cfamAddr << cfamValue << scomAddr << scomValue;

    // If the stream failed for any reason, remove the FFDC file.
    if (!stream.good())
    {
        trace::err("Unable to write register dump FFDC file: %s",
                   path.string().c_str());
        io_userDataFiles.pop_back();
    }
}

//------------------------------------------------------------------------------

std::string __getMessageRegistry(AnalysisType i_type)
{
    if (AnalysisType::SYSTEM_CHECKSTOP == i_type)
    {
        return "org.open_power.HwDiags.Error.Checkstop";
    }
    else if (AnalysisType::TERMINATE_IMMEDIATE == i_type)
    {
        return "org.open_power.HwDiags.Error.Predictive";
    }

    return "org.open_power.HwDiags.Error.Informational"; // default
}

//------------------------------------------------------------------------------

std::string __getMessageSeverity(AnalysisType i_type)
{
    // Default severity is informational (no service action required).
    LogSvr::Entry::Level severity = LogSvr::Entry::Level::Informational;

    if (AnalysisType::SYSTEM_CHECKSTOP == i_type)
    {
        // System checkstops are always unrecoverable errors (service action
        // required).
        severity = LogSvr::Entry::Level::Error;
    }
    else if (AnalysisType::TERMINATE_IMMEDIATE == i_type)
    {
        // TIs will be reported as a predicive error (service action required).
        severity = LogSvr::Entry::Level::Warning;
    }

    // Convert the message severity to a string.
    return LogSvr::Entry::convertLevelToString(severity);
}

//------------------------------------------------------------------------------

uint32_t commitPel(const ServiceData& i_servData)
{
    uint32_t o_plid = 0; // default, zero indicates PEL was not created

    // The message registry will require additional log data to fill in keywords
    // and additional log data.
    std::map<std::string, std::string> logData;

    // Keep track of the temporary files associated with the user data FFDC.
    // WARNING: Once the objects stored in this vector go out of scope, the
    //          temporary files will be deleted. So they must remain in scope
    //          until the PEL is submitted.
    std::vector<util::FFDCFile> userDataFiles;

    // Set the subsystem in the primary SRC.
    i_servData.addSrcSubsystem(logData);

    // Set words 6-9 of the SRC.
    __setSrc(i_servData.getRootCause(), logData);

    // Add the list of callouts to the PEL.
    __addCalloutList(i_servData, userDataFiles);

    // Add the Hostboot scratch register to the PEL.
    __captureHostbootScratchRegisters(userDataFiles);

    // Add the callout FFDC to the PEL.
    __addCalloutFFDC(i_servData, userDataFiles);

    // Capture the complete signature list.
    __captureSignatureList(i_servData.getIsolationData(), userDataFiles);

    // Capture the complete signature list.
    __captureRegisterDump(i_servData.getIsolationData(), userDataFiles);

    // Now, that all of the user data files have been created, transform the
    // data into the proper format for the PEL.
    std::vector<util::FFDCTuple> userData;
    util::transformFFDC(userDataFiles, userData);

    // Get the message registry entry for this failure.
    auto message = __getMessageRegistry(i_servData.getAnalysisType());

    // Get the message severity for this failure.
    auto severity = __getMessageSeverity(i_servData.getAnalysisType());

    // Create the PEL
    o_plid = util::dbus::createPel(message, severity, logData, userData);

    if (0 == o_plid)
    {
        trace::err("Error while creating event log entry");
    }

    // Return the platorm log ID of the error.
    return o_plid;
}

} // namespace analyzer
