#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,
    FFDC_SCRATCH_SIG     = 0x05,

    // 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();
    }
}

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

void __captureScratchRegSignature(std::vector<util::FFDCFile>& io_userDataFiles)
{
    // If analysis was interrupted by a system checkstop, there may exist an
    // error signature within Hostboot scratch registers 9 (scom: 0x00050180,
    // fsi: 0x2980) and 10 (scom: 0x00050181, fsi: 0x2981) which indicates the
    // signature from the interrupted analysis. If data exists within those
    // registers a user data section will be created in the PEL to record it.

    uint32_t reg9Addr  = 0x2980;
    uint32_t reg10Addr = 0x2981;

    uint32_t chipId = 0; // stored in reg9
    uint32_t sigId  = 0; // stored in reg10

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

        if (0 != util::pdbg::getCfam(priProc, reg10Addr, sigId))
        {
            sigId = 0; // just in case
        }
    }

    // If any non-zero data was found in the registers, add them to the FFDC.
    if (0 != chipId || 0 != sigId)
    {
        // Create a new entry for this user data section.
        io_userDataFiles.emplace_back(util::FFDCFormat::Custom,
                                      FFDC_SCRATCH_SIG, FFDC_VERSION1);

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

        stream << chipId << sigId;

        // 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 signature stored in the scratch regs if it exists.
    __captureScratchRegSignature(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
