#include "dump_utils.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>

#include <format>
#include <fstream>
#include <string>

namespace openpower::dump::util
{
using namespace phosphor::logging;

static void monitorDumpCreation(const std::string& path, const uint32_t timeout)
{
    bool inProgress = true;
    auto bus = sdbusplus::bus::new_system();
    auto match = sdbusplus::bus::match_t(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(
            path, "xyz.openbmc_project.Common.Progress"),
        [&](sdbusplus::message_t& msg) {
        std::string interface;
        std::map<std::string, std::variant<std::string, uint8_t>> property;
        msg.read(interface, property);

        const auto dumpStatus = property.find("Status");
        if (dumpStatus != property.end())
        {
            const std::string* status =
                std::get_if<std::string>(&(dumpStatus->second));
            if (status &&
                *status !=
                    "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
            {
                lg2::info("Dump status({STATUS}) : path={PATH}", "STATUS",
                          status->c_str(), "PATH", path.c_str());
                inProgress = false;
            }
        }
    });

    // Timeout management
    for (uint32_t secondsCount = 0; inProgress && secondsCount < timeout;
         ++secondsCount)
    {
        bus.wait(std::chrono::seconds(1));
        bus.process_discard();
    }

    if (inProgress)
    {
        lg2::error("Dump progress timeout; dump may not be complete.");
    }
}

void requestSBEDump(const uint32_t failingUnit, const uint32_t eid,
                    SBETypes sbeType)
{
    lg2::info(
        "Requesting Dump PEL({EID}) chip({CHIPTYPE}) position({FAILINGUNIT})",
        "EID", eid, "CHIPTYPE", sbeTypeAttributes.at(sbeType).chipName,
        "FAILINGUNIT", failingUnit);

    constexpr auto path = "/xyz/openbmc_project/dump/system";
    auto dumpRequestType = sbeTypeAttributes.at(sbeType).dumpType;
    constexpr auto interface = "xyz.openbmc_project.Dump.Create";
    constexpr auto function = "CreateDump";

    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto service = getService(bus, interface, path);
        auto method = bus.new_method_call(service.c_str(), path, interface,
                                          function);

        std::unordered_map<std::string, std::variant<std::string, uint64_t>>
            createParams = {
                {"com.ibm.Dump.Create.CreateParameters.DumpType",
                 dumpRequestType},
                {"com.ibm.Dump.Create.CreateParameters.ErrorLogId",
                 uint64_t(eid)},
                {"com.ibm.Dump.Create.CreateParameters.FailingUnitId",
                 uint64_t(failingUnit)}};

        method.append(createParams);
        sdbusplus::message::object_path reply;
        bus.call(method).read(reply);

        monitorDumpCreation(reply.str, SBE_DUMP_TIMEOUT);
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error("D-Bus call createDump exception OBJPATH={OBJPATH}, "
                   "INTERFACE={INTERFACE}, EXCEPTION={ERROR}",
                   "OBJPATH", path, "INTERFACE", interface, "ERROR", e);
        constexpr auto ERROR_DUMP_DISABLED =
            "xyz.openbmc_project.Dump.Create.Error.Disabled";
        if (e.name() == ERROR_DUMP_DISABLED)
        {
            // Dump is disabled, Skip the dump collection.
            lg2::info("Dump is disabled unit({FAILINGUNIT}), "
                      "skipping dump collection",
                      "FAILINGUNIT", failingUnit);
        }
        else
        {
            throw;
        }
    }
    catch (const std::exception& e)
    {
        throw e;
    }
}

std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
                       const std::string& path)
{
    constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
    constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
    constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
    try
    {
        auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
                                          MAPPER_INTERFACE, "GetObject");

        mapper.append(path, std::vector<std::string>({intf}));

        auto mapperResponseMsg = bus.call(mapper);
        std::map<std::string, std::vector<std::string>> mapperResponse;
        mapperResponseMsg.read(mapperResponse);

        if (mapperResponse.empty())
        {
            lg2::error(
                "Empty mapper response for GetObject interface({INTERFACE}), "
                "path({PATH})",
                "INTERFACE", intf, "PATH", path);

            throw std::runtime_error("Empty mapper response for GetObject");
        }
        return mapperResponse.begin()->first;
    }
    catch (const sdbusplus::exception_t& ex)
    {
        lg2::error(
            "Mapper call failed for GetObject errorMsg({ERROR}), path({PATH}),"
            "interface({INTERFACE})",
            "ERROR", ex, "PATH", path, "INTERFACE", intf);

        throw;
    }
}

} // namespace openpower::dump::util
