#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
