/**
 * Copyright © 2021 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

#include "fapi_data_process.hpp"
#include "pel.hpp"
#include "sbe_ffdc_handler.hpp"
#include "temporary_file.hpp"

#include <ekb/hwpf/fapi2/include/return_code_defs.H>
#include <ekb/hwpf/fapi2/include/target_types.H>
#include <libekb.H>

#include <phosphor-logging/lg2.hpp>

#include <format>
#include <new>

namespace openpower
{
namespace pels
{
namespace sbe
{

constexpr uint32_t sbeMaxFfdcPackets = 20;
constexpr uint16_t p10FfdcMagicCode = 0xFFDC;
constexpr uint16_t pozFfdcMagicCode = 0xFBAD;
constexpr uint16_t p10FfdcSkipWords = 2;
constexpr uint16_t pozFfdcSkipWords = 3;

struct p10FfdcHeader
{
    uint32_t magic_bytes:16;
    uint32_t lengthinWords:16;
    uint32_t seqId:16;
    uint32_t cmdClass:8;
    uint32_t cmd:8;
    uint32_t fapiRc;
} __attribute__((packed));

struct pozFfdcHeader
{
    uint32_t magicByte:16;
    uint32_t lengthinWords:16;
    uint32_t seqId:16;
    uint32_t cmdClass:8;
    uint32_t cmd:8;
    uint32_t slid:16;
    uint32_t severity:8;
    uint32_t chipId:8;
    uint32_t fapiRc;
} __attribute__((packed));

using namespace phosphor::logging;

SbeFFDC::SbeFFDC(const AdditionalData& aData, const PelFFDC& files) :
    ffdcType(FFDC_TYPE_NONE), chipType(fapi2::TARGET_TYPE_PROC_CHIP)
{
    lg2::info("SBE FFDC processing requested");

    // SRC6 field in the additional data contains Processor position
    // associated to the SBE FFDC
    //"[0:15] chip position"
    auto src6 = aData.getValue("SRC6");
    if (src6 == std::nullopt)
    {
        lg2::error("Fail to extract SRC6 data: failing to get proc index");
        return;
    }
    try
    {
        chipPos = (std::stoi(src6.value()) & 0xFFFF0000) >> 16;
    }
    catch (const std::exception& err)
    {
        lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
        return;
    }
    auto type = aData.getValue("CHIP_TYPE");
    if (type != std::nullopt)
    {
        try
        {
            chipType = std::stoi(type.value());
        }
        catch (const std::exception& err)
        {
            lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
            return;
        }
    }

    if (files.empty())
    {
        lg2::info("SbeFFDC : No files found, skipping ffdc processing");
        return;
    }

    for (const auto& file : files)
    {
        if ((file.format == UserDataFormat::custom) &&
            (file.subType == sbeFFDCSubType))
        {
            // Process SBE file.
            parse(file.fd);
        }
    }
}

void SbeFFDC::parse(int fd)
{
    lg2::info("SBE FFDC file fd:({FD}), parsing started", "FD", fd);

    uint32_t ffdcBufOffset = 0;
    uint32_t pktCount = 0;

    // get SBE FFDC data.
    auto ffdcData = util::readFD(fd);
    if (ffdcData.empty())
    {
        lg2::error("Empty SBE FFDC file fd:({FD}), skipping", "FD", fd);
        return;
    }

    while ((ffdcBufOffset < ffdcData.size()) && (sbeMaxFfdcPackets != pktCount))
    {
        sbeFfdcPacketType ffdcPkt;
        // Next un-extracted FFDC Packet
        uint16_t magicBytes =
            *(reinterpret_cast<uint16_t*>(ffdcData.data() + ffdcBufOffset));
        magicBytes = ntohs(magicBytes);
        uint32_t pktLenWords = 0;
        uint16_t lenWords = 0;
        if (magicBytes == p10FfdcMagicCode)
        {
            p10FfdcHeader* ffdc = reinterpret_cast<p10FfdcHeader*>(
                ffdcData.data() + ffdcBufOffset);
            lenWords = ntohs(ffdc->lengthinWords);
            auto fapiRc = ntohl(ffdc->fapiRc);

            lg2::info(
                "P10 FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
                "Fapirc:{FAPI_RC}",
                "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
                fapiRc);

            ffdcPkt.fapiRc = fapiRc;
            // Not interested in the first 2 words (these are not ffdc)
            pktLenWords = lenWords - p10FfdcSkipWords;
            ffdcPkt.ffdcLengthInWords = pktLenWords;
            if (pktLenWords)
            {
                ffdcPkt.ffdcData = new uint32_t[pktLenWords];
                memcpy(ffdcPkt.ffdcData,
                       ((reinterpret_cast<uint32_t*>(ffdc)) + p10FfdcSkipWords),
                       (pktLenWords * sizeof(uint32_t)));
            }
            else
            {
                lg2::error("FFDC packet size is zero skipping");
                return;
            }
            pktCount++;
        }
        else if (magicBytes == pozFfdcMagicCode)
        {
            pozFfdcHeader* ffdc = reinterpret_cast<pozFfdcHeader*>(
                ffdcData.data() + ffdcBufOffset);
            lenWords = ntohs(ffdc->lengthinWords);
            auto fapiRc = ntohl(ffdc->fapiRc);

            lg2::info(
                "P0Z FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
                "Fapirc:{FAPI_RC}",
                "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
                fapiRc);

            ffdcPkt.fapiRc = fapiRc;
            // Not interested in the first 3 words (these are not ffdc)
            pktLenWords = lenWords - pozFfdcSkipWords;
            ffdcPkt.ffdcLengthInWords = pktLenWords;
            if (pktLenWords)
            {
                ffdcPkt.ffdcData = new uint32_t[pktLenWords];
                memcpy(ffdcPkt.ffdcData,
                       ((reinterpret_cast<uint32_t*>(ffdc)) + pozFfdcSkipWords),
                       (pktLenWords * sizeof(uint32_t)));
            }
            else
            {
                lg2::error("FFDC packet size is zero skipping");
                return;
            }
        }
        else
        {
            lg2::error("Invalid FFDC magic code in Header: Skipping ");
            return;
        }

        // SBE FFDC processing is not required for SBE Plat errors RCs.
        // Plat errors processing is driven by SBE provided user data
        // plugins, which need to link with PEL tool infrastructure.
        if (ffdcPkt.fapiRc != fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA)
        {
            process(ffdcPkt);
        }
        else
        {
            lg2::info("SBE FFDC: Internal FFDC packet");
        }

        // Update Buffer offset in Bytes
        ffdcBufOffset += lenWords * sizeof(uint32_t);
    }
    if (pktCount == sbeMaxFfdcPackets)
    {
        lg2::error("Received more than the limit of ({SBEMAXFFDCPACKETS}) FFDC "
                   "packets, processing only ({PKTCOUNT})",
                   "SBEMAXFFDCPACKETS", sbeMaxFfdcPackets, "PKTCOUNT",
                   pktCount);
    }
}

void SbeFFDC::process(const sbeFfdcPacketType& ffdcPkt)
{
    using json = nlohmann::json;

    // formated FFDC data structure after FFDC packet processing
    FFDC ffdc;

    if (!pdbg_targets_init(NULL))
    {
        lg2::error("pdbg_targets_init failed, skipping ffdc processing");
        return;
    }

    if (libekb_init())
    {
        lg2::error("libekb_init failed, skipping ffdc processing");
        return;
    }

    try
    {
        // libekb provided wrapper function to convert SBE FFDC
        // in to known ffdc structure.
        libekb_get_sbe_ffdc(ffdc, ffdcPkt, chipPos, chipType);
    }
    catch (...)
    {
        lg2::error("libekb_get_sbe_ffdc failed, skipping ffdc processing");
        return;
    }

    // update FFDC type class membeir for hwp specific packet
    // Assumption SBE FFDC contains only one hwp FFDC packet.
    ffdcType = ffdc.ffdc_type;

    // To store callouts details in json format as per pel expectation.
    json pelJSONFmtCalloutDataList;
    pelJSONFmtCalloutDataList = json::array();

    // To store other user data from FFDC.
    openpower::pels::phal::FFDCData ffdcUserData;

    // Get FFDC and required info to include in PEL
    openpower::pels::phal::convertFAPItoPELformat(
        ffdc, pelJSONFmtCalloutDataList, ffdcUserData);

    // Get callout information and sore in to file.
    auto calloutData = pelJSONFmtCalloutDataList.dump();
    util::TemporaryFile ffdcFile(calloutData.c_str(), calloutData.size());

    // Create json callout type pel FFDC file structre.
    PelFFDCfile pf;
    pf.format = openpower::pels::UserDataFormat::json;
    pf.subType = openpower::pels::jsonCalloutSubtype;
    pf.version = 0x01;
    pf.fd = ffdcFile.getFd();
    ffdcFiles.push_back(pf);

    // save the file path to delete the file after usage.
    paths.emplace_back(ffdcFile.getPath(), pf.fd);

    // Format ffdc user data and create new file.
    std::string data;
    for (auto& d : ffdcUserData)
    {
        data += d.first + " = " + d.second + "\n";
    }
    util::TemporaryFile pelDataFile(data.c_str(), data.size());
    PelFFDCfile pdf;
    pdf.format = openpower::pels::UserDataFormat::text;
    pdf.version = 0x01;
    pdf.fd = pelDataFile.getFd();
    pdf.subType = 0;
    ffdcFiles.push_back(pdf);

    paths.emplace_back(pelDataFile.getPath(), pdf.fd);
}

std::optional<LogSeverity> SbeFFDC::getSeverity()
{
    if (ffdcType == FFDC_TYPE_SPARE_CLOCK_INFO)
    {
        lg2::info(
            "Found spare clock error, changing severity to informational");
        return LogSeverity::Informational;
    }
    return std::nullopt;
}

} // namespace sbe
} // namespace pels
} // namespace openpower
