/**
 * 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/log.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)
{
    log<level::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)
    {
        log<level::ERR>("Fail to extract SRC6 data: failing to get proc index");
        return;
    }
    try
    {
        chipPos = (std::stoi(src6.value()) & 0xFFFF0000) >> 16;
    }
    catch (const std::exception& err)
    {
        log<level::ERR>(
            std::format("Conversion failure errormsg({})", err.what()).c_str());
        return;
    }
    auto type = aData.getValue("CHIP_TYPE");
    if (type != std::nullopt)
    {
        try
        {
            chipType = std::stoi(type.value());
        }
        catch (const std::exception& err)
        {
            log<level::ERR>(
                std::format("Conversion failure errormsg({})", err.what())
                    .c_str());
            return;
        }
    }

    if (files.empty())
    {
        log<level::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)
{
    log<level::INFO>(
        std::format("SBE FFDC file fd:({}), parsing started", fd).c_str());

    uint32_t ffdcBufOffset = 0;
    uint32_t pktCount = 0;

    // get SBE FFDC data.
    auto ffdcData = util::readFD(fd);
    if (ffdcData.empty())
    {
        log<level::ERR>(
            std::format("Empty SBE FFDC file fd:({}), skipping", fd).c_str());
        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);

            auto msg =
                std::format("P10 FFDC magic: {} length in words:{} Fapirc:{}",
                            magicBytes, lenWords, fapiRc);
            log<level::INFO>(msg.c_str());

            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
            {
                log<level::ERR>("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);

            auto msg =
                std::format("P0Z FFDC magic: {} length in words:{} Fapirc:{}",
                            magicBytes, lenWords, fapiRc);
            log<level::INFO>(msg.c_str());

            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
            {
                log<level::ERR>("FFDC packet size is zero skipping");
                return;
            }
        }
        else
        {
            log<level::ERR>("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
        {
            log<level::INFO>("SBE FFDC: Internal FFDC packet");
        }

        // Update Buffer offset in Bytes
        ffdcBufOffset += lenWords * sizeof(uint32_t);
    }
    if (pktCount == sbeMaxFfdcPackets)
    {
        log<level::ERR>(std::format("Received more than the limit of ({})"
                                    " FFDC packets, processing only ({})",
                                    sbeMaxFfdcPackets, pktCount)
                            .c_str());
    }
}

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))
    {
        log<level::ERR>("pdbg_targets_init failed, skipping ffdc processing");
        return;
    }

    if (libekb_init())
    {
        log<level::ERR>("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 (...)
    {
        log<level::ERR>("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)
    {
        log<level::INFO>(
            "Found spare clock error, changing severity to informational");
        return LogSeverity::Informational;
    }
    return std::nullopt;
}

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