#include "file_io_type_pel.hpp"

#include "common/utils.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <libpldm/base.h>
#include <libpldm/file_io.h>
#include <stdint.h>
#include <systemd/sd-bus.h>
#include <unistd.h>

#include <org/open_power/Logging/PEL/server.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>

#include <exception>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{
using namespace sdbusplus::xyz::openbmc_project::Logging::server;
using namespace sdbusplus::org::open_power::Logging::server;

namespace detail
{
/**
 * @brief Finds the Entry::Level value for the severity of the PEL
 *        passed in.
 *
 * The severity byte is at offset 10 in the User Header section,
 * which is always after the 48 byte Private Header section.
 *
 * @param[in] pelFileName - The file containing the PEL
 *
 * @return Entry::Level - The severity value for the Entry
 */
Entry::Level getEntryLevelFromPEL(const std::string& pelFileName)
{
    const std::map<uint8_t, Entry::Level> severityMap{
        {0x00, Entry::Level::Informational}, // Informational event
        {0x10, Entry::Level::Warning},       // Recoverable error
        {0x20, Entry::Level::Warning},       // Predictive error
        {0x40, Entry::Level::Error},         // Unrecoverable error
        {0x50, Entry::Level::Error},         // Critical error
        {0x60, Entry::Level::Error},         // Error from a diagnostic test
        {0x70, Entry::Level::Warning}        // Recoverable symptom
    };

    const size_t severityOffset = 0x3A;

    size_t size = 0;
    if (fs::exists(pelFileName))
    {
        size = fs::file_size(pelFileName);
    }

    if (size > severityOffset)
    {
        std::ifstream pel{pelFileName};
        if (pel.good())
        {
            pel.seekg(severityOffset);

            uint8_t sev;
            pel.read(reinterpret_cast<char*>(&sev), 1);

            // Get the type
            sev = sev & 0xF0;

            auto entry = severityMap.find(sev);
            if (entry != severityMap.end())
            {
                return entry->second;
            }
        }
        else
        {
            error("Unable to open PEL file {PEL_FILE_NAME}", "PEL_FILE_NAME",
                  pelFileName);
        }
    }

    return Entry::Level::Error;
}
} // namespace detail

int PelHandler::readIntoMemory(uint32_t offset, uint32_t& length,
                               uint64_t address,
                               oem_platform::Handler* /*oemPlatformHandler*/)
{
    static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
    static constexpr auto logInterface = "org.open_power.Logging.PEL";

    auto& bus = pldm::utils::DBusHandler::getBus();

    try
    {
        auto service = pldm::utils::DBusHandler().getService(logObjPath,
                                                             logInterface);
        auto method = bus.new_method_call(service.c_str(), logObjPath,
                                          logInterface, "GetPEL");
        method.append(fileHandle);
        auto reply = bus.call(
            method,
            std::chrono::duration_cast<microsec>(sec(DBUS_TIMEOUT)).count());
        sdbusplus::message::unix_fd fd{};
        reply.read(fd);
        auto rc = transferFileData(fd, true, offset, length, address);
        return rc;
    }
    catch (const std::exception& e)
    {
        error(
            "GetPEL D-Bus call failed, PEL id = 0x{FILE_HANDLE}, error ={ERR_EXCEP}",
            "FILE_HANDLE", lg2::hex, fileHandle, "ERR_EXCEP", e.what());
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

int PelHandler::read(uint32_t offset, uint32_t& length, Response& response,
                     oem_platform::Handler* /*oemPlatformHandler*/)
{
    static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
    static constexpr auto logInterface = "org.open_power.Logging.PEL";
    auto& bus = pldm::utils::DBusHandler::getBus();

    try
    {
        auto service = pldm::utils::DBusHandler().getService(logObjPath,
                                                             logInterface);
        auto method = bus.new_method_call(service.c_str(), logObjPath,
                                          logInterface, "GetPEL");
        method.append(fileHandle);
        auto reply = bus.call(
            method,
            std::chrono::duration_cast<microsec>(sec(DBUS_TIMEOUT)).count());
        sdbusplus::message::unix_fd fd{};
        reply.read(fd);

        off_t fileSize = lseek(fd, 0, SEEK_END);
        if (fileSize == -1)
        {
            error("file seek failed");
            return PLDM_ERROR;
        }
        if (offset >= fileSize)
        {
            error(
                "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE} FILE_HANDLE{FILE_HANDLE}",
                "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE",
                fileHandle);
            return PLDM_DATA_OUT_OF_RANGE;
        }
        if (offset + length > fileSize)
        {
            length = fileSize - offset;
        }
        auto rc = lseek(fd, offset, SEEK_SET);
        if (rc == -1)
        {
            error("file seek failed");
            return PLDM_ERROR;
        }
        size_t currSize = response.size();
        response.resize(currSize + length);
        auto filePos = reinterpret_cast<char*>(response.data());
        filePos += currSize;
        rc = ::read(fd, filePos, length);
        if (rc == -1)
        {
            error("file read failed");
            return PLDM_ERROR;
        }
        if (rc != length)
        {
            error(
                "mismatch between number of characters to read and the length read, LENGTH={LEN} COUNT={CNT}",
                "LEN", length, "CNT", rc);
            return PLDM_ERROR;
        }
    }
    catch (const std::exception& e)
    {
        error(
            "GetPEL D-Bus call failed on PEL ID 0x{FILE_HANDLE}, error ={ERR_EXCEP}",
            "FILE_HANDLE", lg2::hex, fileHandle, "ERR_EXCEP", e.what());
        return PLDM_ERROR;
    }
    return PLDM_SUCCESS;
}

int PelHandler::writeFromMemory(uint32_t offset, uint32_t length,
                                uint64_t address,
                                oem_platform::Handler* /*oemPlatformHandler*/)
{
    char tmpFile[] = "/tmp/pel.XXXXXX";
    int fd = mkstemp(tmpFile);
    if (fd == -1)
    {
        error("failed to create a temporary pel, ERROR={ERR}", "ERR", errno);
        return PLDM_ERROR;
    }
    close(fd);
    fs::path path(tmpFile);

    auto rc = transferFileData(path, false, offset, length, address);
    if (rc == PLDM_SUCCESS)
    {
        rc = storePel(path.string());
    }
    return rc;
}

int PelHandler::fileAck(uint8_t fileStatus)
{
    static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
    static constexpr auto logInterface = "org.open_power.Logging.PEL";
    static std::string service;
    auto& bus = pldm::utils::DBusHandler::getBus();

    if (service.empty())
    {
        try
        {
            service = pldm::utils::DBusHandler().getService(logObjPath,
                                                            logInterface);
        }
        catch (const sdbusplus::exception_t& e)
        {
            error("Mapper call failed when trying to find logging service "
                  "to ack PEL ID {FILE_HANDLE} error = {ERR_EXCEP}",
                  "FILE_HANDLE", lg2::hex, fileHandle, "ERR_EXCEP", e);
            return PLDM_ERROR;
        }
    }

    if (fileStatus == PLDM_SUCCESS)
    {
        try
        {
            auto method = bus.new_method_call(service.c_str(), logObjPath,
                                              logInterface, "HostAck");
            method.append(fileHandle);
            bus.call_noreply(method);
        }
        catch (const std::exception& e)
        {
            error(
                "HostAck D-Bus call failed on PEL ID {FILE_HANDLE}, error = {ERR_EXCEP}",
                "FILE_HANDLE", lg2::hex, fileHandle, "ERR_EXCEP", e);
            return PLDM_ERROR;
        }
    }
    else
    {
        PEL::RejectionReason reason{};
        if (fileStatus == PLDM_FULL_FILE_DISCARDED)
        {
            reason = PEL::RejectionReason::HostFull;
        }
        else if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
        {
            reason = PEL::RejectionReason::BadPEL;
        }
        else
        {
            error(
                "Invalid file status {STATUS} in PEL file ack response for PEL {FILE_HANDLE}",
                "STATUS", lg2::hex, fileStatus, "FILE_HANDLE", lg2::hex,
                fileHandle);
            return PLDM_ERROR;
        }

        try
        {
            auto method = bus.new_method_call(service.c_str(), logObjPath,
                                              logInterface, "HostReject");
            method.append(fileHandle, reason);
            bus.call_noreply(method);
        }
        catch (const std::exception& e)
        {
            error("HostReject D-Bus call failed on PEL ID {FILE_HANDLE}, "
                  "error = {ERR_EXCEP}, status = {STATUS}",
                  "FILE_HANDLE", lg2::hex, fileHandle, "ERR_EXCEP", e, "STATUS",
                  lg2::hex, fileStatus);
            return PLDM_ERROR;
        }
    }

    return PLDM_SUCCESS;
}

int PelHandler::storePel(std::string&& pelFileName)
{
    static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
    static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";

    auto& bus = pldm::utils::DBusHandler::getBus();

    try
    {
        auto service = pldm::utils::DBusHandler().getService(logObjPath,
                                                             logInterface);
        using namespace sdbusplus::xyz::openbmc_project::Logging::server;
        std::map<std::string, std::string> addlData{};
        auto severity =
            sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
                detail::getEntryLevelFromPEL(pelFileName));
        addlData.emplace("RAWPEL", std::move(pelFileName));

        auto method = bus.new_method_call(service.c_str(), logObjPath,
                                          logInterface, "Create");
        method.append("xyz.openbmc_project.Host.Error.Event", severity,
                      addlData);
        bus.call_noreply(method);
    }
    catch (const std::exception& e)
    {
        error(
            "failed to make a d-bus call to PEL daemon, PEL_FILE_NAME={PEL_FILE_NAME), ERROR={ERR_EXCEP}",
            "PEL_FILE_NAME", pelFileName, "ERR_EXCEP", e.what());
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

int PelHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
                      oem_platform::Handler* /*oemPlatformHandler*/)
{
    int rc = PLDM_SUCCESS;

    if (offset > 0)
    {
        error("Offset is non zero");
        return PLDM_ERROR;
    }

    char tmpFile[] = "/tmp/pel.XXXXXX";
    auto fd = mkstemp(tmpFile);
    if (fd == -1)
    {
        error("failed to create a temporary pel, ERROR={ERR}", "ERR", errno);
        return PLDM_ERROR;
    }

    size_t written = 0;
    do
    {
        if ((rc = ::write(fd, buffer, length - written)) == -1)
        {
            break;
        }
        written += rc;
        buffer += rc;
    } while (rc && written < length);
    close(fd);

    if (rc == -1)
    {
        error("file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
              "ERR", errno, "LEN", length, "OFFSET", offset);
        fs::remove(tmpFile);
        return PLDM_ERROR;
    }

    if (written == length)
    {
        fs::path path(tmpFile);
        rc = storePel(path.string());
        if (rc != PLDM_SUCCESS)
        {
            error("save PEL failed, ERROR = {RC} tmpFile = {TMP_FILE}", "RC",
                  rc, "TMP_FILE", tmpFile);
        }
    }

    return rc;
}

} // namespace responder
} // namespace pldm
