#include "file_io_type_vpd.hpp"

#include "libpldm/base.h"
#include "libpldm/file_io.h"

#include "common/utils.hpp"

#include <stdint.h>

#include <phosphor-logging/lg2.hpp>

#include <iostream>

PHOSPHOR_LOG2_USING;

typedef uint8_t byte;

namespace pldm
{
namespace responder
{
int keywordHandler::read(uint32_t offset, uint32_t& length, Response& response,
                         oem_platform::Handler* /*oemPlatformHandler*/)
{
    const char* keywrdObjPath =
        "/xyz/openbmc_project/inventory/system/chassis/motherboard";
    const char* keywrdPropName = "PD_D";
    const char* keywrdInterface = "com.ibm.ipzvpd.PSPD";

    std::variant<std::vector<byte>> keywrd;

    try
    {
        auto& bus = pldm::utils::DBusHandler::getBus();
        auto service = pldm::utils::DBusHandler().getService(keywrdObjPath,
                                                             keywrdInterface);
        auto method = bus.new_method_call(service.c_str(), keywrdObjPath,
                                          "org.freedesktop.DBus.Properties",
                                          "Get");
        method.append(keywrdInterface, keywrdPropName);
        auto reply = bus.call(method, dbusTimeout);
        reply.read(keywrd);
    }
    catch (const std::exception& e)
    {
        error(
            "Get keyword error from dbus interface :{KEYWORD_INTF} ERROR={ERR_EXCEP}",
            "KEYWORD_INTF", keywrdInterface, "ERR_EXCEP", e.what());
    }

    uint32_t keywrdSize = std::get<std::vector<byte>>(keywrd).size();
    if (length < keywrdSize)
    {
        error(
            "length requested is less the keyword size, length:{LEN} keyword size:{KEYWORD_SIZE}",
            "LEN", length, "KEYWORD_SIZE", keywrdSize);
        return PLDM_ERROR_INVALID_DATA;
    }

    namespace fs = std::filesystem;
    constexpr auto keywrdDirPath = "/tmp/pldm/";
    constexpr auto keywrdFilePath = "/tmp/pldm/vpdKeywrd.bin";

    if (!fs::exists(keywrdDirPath))
    {
        fs::create_directories(keywrdDirPath);
        fs::permissions(keywrdDirPath,
                        fs::perms::others_read | fs::perms::owner_write);
    }

    std::ofstream keywrdFile(keywrdFilePath);
    auto fd = open(keywrdFilePath, std::ios::out | std::ofstream::binary);
    if (!keywrdFile)
    {
        error("VPD keyword file open error: {KEYWORD_FILE_PATH} errno: {ERR}",
              "KEYWORD_FILE_PATH", keywrdFilePath, "ERR", errno);
        pldm::utils::reportError(
            "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileOpenError");
        return PLDM_ERROR;
    }

    if (offset > keywrdSize)
    {
        error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
              "OFFSET", offset, "FILE_SIZE", keywrdSize);
        return PLDM_DATA_OUT_OF_RANGE;
    }

    // length of keyword data should be same as keyword data size in dbus
    // object
    length = static_cast<uint32_t>(keywrdSize) - offset;

    auto returnCode = lseek(fd, offset, SEEK_SET);
    if (returnCode == -1)
    {
        error("Could not find keyword data at given offset. File Seek failed");
        return PLDM_ERROR;
    }

    keywrdFile.write((const char*)std::get<std::vector<byte>>(keywrd).data(),
                     keywrdSize);
    if (keywrdFile.bad())
    {
        error("Error while writing to file: {KEYWORD_FILE_PATH}",
              "KEYWORD_FILE_PATH", keywrdFilePath);
    }
    keywrdFile.close();

    auto rc = readFile(keywrdFilePath, offset, keywrdSize, response);
    fs::remove(keywrdFilePath);
    if (rc)
    {
        error("Read error for keyword file with size: {KEYWORD_SIZE}",
              "KEYWORD_SIZE", keywrdSize);
        pldm::utils::reportError(
            "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileReadError");
        return PLDM_ERROR;
    }
    return PLDM_SUCCESS;
}
} // namespace responder
} // namespace pldm
