#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
