#include "file_io_type_dump.hpp"

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

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

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

#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Dump/NewDump/server.hpp>

#include <exception>
#include <filesystem>
#include <iostream>

using namespace pldm::utils;

namespace pldm
{
namespace responder
{

static constexpr auto nbdInterfaceDefault = "/dev/nbd1";
static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump";

int DumpHandler::fd = -1;

static std::string findDumpObjPath(uint32_t fileHandle)
{
    static constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
    static constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
    static constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
    static constexpr auto systemDumpEntry =
        "xyz.openbmc_project.Dump.Entry.System";
    auto& bus = pldm::utils::DBusHandler::getBus();

    try
    {
        std::vector<std::string> paths;
        auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
                                          MAPPER_INTERFACE, "GetSubTreePaths");
        method.append(dumpObjPath);
        method.append(0);
        method.append(std::vector<std::string>({systemDumpEntry}));
        auto reply = bus.call(method);
        reply.read(paths);
        for (const auto& path : paths)
        {
            auto dumpId = pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
                path.c_str(), "SourceDumpId", systemDumpEntry);
            if (dumpId == fileHandle)
            {
                return path;
            }
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
                  << e.what() << "\n";
    }

    std::cerr << "failed to find dump object for dump id " << fileHandle
              << "\n";
    return {};
}

int DumpHandler::newFileAvailable(uint64_t length)
{
    static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
    auto& bus = pldm::utils::DBusHandler::getBus();

    try
    {
        auto service =
            pldm::utils::DBusHandler().getService(dumpObjPath, dumpInterface);
        using namespace sdbusplus::xyz::openbmc_project::Dump::server;
        auto method = bus.new_method_call(service.c_str(), dumpObjPath,
                                          dumpInterface, "Notify");
        method.append(
            sdbusplus::xyz::openbmc_project::Dump::server::convertForMessage(
                NewDump::DumpType::System),
            fileHandle, length);
        bus.call_noreply(method);
    }
    catch (const std::exception& e)
    {
        std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
                  << e.what() << "\n";
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

static std::string getOffloadUri(uint32_t fileHandle)
{
    auto path = findDumpObjPath(fileHandle);
    if (path.empty())
    {
        return {};
    }

    std::string nbdInterface{};
    try
    {
        nbdInterface = pldm::utils::DBusHandler().getDbusProperty<std::string>(
            path.c_str(), "OffloadUri", dumpEntry);
    }
    catch (const std::exception& e)
    {
        std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
                  << e.what() << "\n";
    }

    if (nbdInterface == "")
    {
        nbdInterface = nbdInterfaceDefault;
    }

    return nbdInterface;
}

int DumpHandler::writeFromMemory(uint32_t offset, uint32_t length,
                                 uint64_t address)
{
    auto nbdInterface = getOffloadUri(fileHandle);
    if (nbdInterface.empty())
    {
        return PLDM_ERROR;
    }

    int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
    if (DumpHandler::fd == -1)
    {
        DumpHandler::fd = open(nbdInterface.c_str(), flags);
        if (DumpHandler::fd == -1)
        {
            std::cerr << "NBD file does not exist at " << nbdInterface
                      << " ERROR=" << errno << "\n";
            return PLDM_ERROR;
        }
    }

    return transferFileData(DumpHandler::fd, false, offset, length, address);
}

int DumpHandler::write(const char* buffer, uint32_t offset, uint32_t& length)
{
    auto nbdInterface = getOffloadUri(fileHandle);
    if (nbdInterface.empty())
    {
        return PLDM_ERROR;
    }

    int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
    if (DumpHandler::fd == -1)
    {
        DumpHandler::fd = open(nbdInterface.c_str(), flags);
        if (DumpHandler::fd == -1)
        {
            std::cerr << "NBD file does not exist at " << nbdInterface
                      << " ERROR=" << errno << "\n";
            return PLDM_ERROR;
        }
    }

    int rc = lseek(DumpHandler::fd, offset, SEEK_SET);
    if (rc == -1)
    {
        std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
                  << "\n";
        return PLDM_ERROR;
    }
    rc = ::write(DumpHandler::fd, buffer, length);
    if (rc == -1)
    {
        std::cerr << "file write failed, ERROR=" << errno
                  << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
        return PLDM_ERROR;
    }
    length = rc;

    return PLDM_SUCCESS;
}

int DumpHandler::fileAck(uint8_t /*fileStatus*/)
{
    if (DumpHandler::fd >= 0)
    {
        auto path = findDumpObjPath(fileHandle);
        if (!path.empty())
        {
            PropertyValue value{true};
            DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
            try
            {
                pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
            }
            catch (const std::exception& e)
            {
                std::cerr
                    << "failed to make a d-bus call to DUMP manager, ERROR="
                    << e.what() << "\n";
            }
            close(DumpHandler::fd);
            DumpHandler::fd = -1;
            return PLDM_SUCCESS;
        }
    }

    return PLDM_ERROR;
}

} // namespace responder
} // namespace pldm
