#include <fmt/format.h>

#include <util/dbus.hpp>
#include <util/trace.hpp>
#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>

namespace util
{
namespace dbus
{
//------------------------------------------------------------------------------

constexpr auto objectMapperService = "xyz.openbmc_project.ObjectMapper";
constexpr auto objectMapperPath = "/xyz/openbmc_project/object_mapper";
constexpr auto objectMapperInterface = "xyz.openbmc_project.ObjectMapper";

constexpr uint8_t terminusIdZero = 0;

/** @brief Find the path and service that implements the given interface */
int find(const std::string& i_interface, std::string& o_path,
         std::string& o_service)
{
    int rc = 1; // assume not success

    auto bus = sdbusplus::bus::new_default();

    try
    {
        constexpr auto function = "GetSubTree";

        auto method = bus.new_method_call(objectMapperService, objectMapperPath,
                                          objectMapperInterface, function);

        // Search the entire dbus tree for the specified interface
        method.append(std::string{"/"}, 0,
                      std::vector<std::string>{i_interface});

        auto reply = bus.call(method);

        DBusSubTree response;
        reply.read(response);

        if (!response.empty())
        {
            // Response is a map of object paths to a map of service, interfaces
            auto object = *(response.begin());
            o_path = object.first;                    // return path
            o_service = object.second.begin()->first; // return service

            rc = 0;                                   // success
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        trace::err("util::dbus::find exception");
        std::string traceMsg = std::string(e.what());
        trace::err(traceMsg.c_str());
    }

    return rc;
}

/** @brief Find the service that implements the given object and interface */
int findService(const std::string& i_interface, const std::string& i_path,
                std::string& o_service)
{
    int rc = 1; // assume not success

    auto bus = sdbusplus::bus::new_default();

    try
    {
        constexpr auto function = "GetObject";

        auto method = bus.new_method_call(objectMapperService, objectMapperPath,
                                          objectMapperInterface, function);

        // Find services that implement the object path, constrain the search
        // to the given interface.
        method.append(i_path, std::vector<std::string>{i_interface});

        auto reply = bus.call(method);

        // response is a map of service names to their interfaces
        std::map<DBusService, DBusInterfaceList> response;
        reply.read(response);

        if (!response.empty())
        {
            // return the service
            o_service = response.begin()->first;

            rc = 0; // success
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        trace::err("util::dbus::map exception");
        std::string traceMsg = std::string(e.what());
        trace::err(traceMsg.c_str());
    }

    return rc;
}

/** @brief Read a property from a dbus object interface */
int getProperty(const std::string& i_interface, const std::string& i_path,
                const std::string& i_service, const std::string& i_property,
                DBusValue& o_response)
{
    int rc = 1; // assume not success

    auto bus = sdbusplus::bus::new_default();

    try
    {
        constexpr auto interface = "org.freedesktop.DBus.Properties";
        constexpr auto function = "Get";

        // calling the get property method
        auto method = bus.new_method_call(i_service.c_str(), i_path.c_str(),
                                          interface, function);

        method.append(i_interface, i_property);
        auto reply = bus.call(method);

        // returning the property value
        reply.read(o_response);

        rc = 0; // success
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        trace::err("util::dbus::getProperty exception");
        std::string traceMsg = std::string(e.what());
        trace::err(traceMsg.c_str());
    }

    return rc;
}

/** @brief Get the IBM compatible names defined for this system */
std::vector<std::string> systemNames()
{
    std::vector<std::string> names;

    constexpr auto interface =
        "xyz.openbmc_project.Configuration.IBMCompatibleSystem";

    DBusService service;
    DBusPath path;

    // find a dbus object and path that implements the interface
    if (0 == find(interface, path, service))
    {
        DBusValue value;

        // compatible system names are implemented as a property
        constexpr auto property = "Names";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, names are in the vector
            names = std::get<std::vector<std::string>>(value);
        }
    }

    return names;
}

/** @brief Transition the host state */
void transitionHost(const HostState i_hostState)
{
    try
    {
        // We will be transitioning host by starting appropriate dbus target
        std::string target = "obmc-host-quiesce@0.target"; // quiesce is default

        // crash (mpipl) mode state requested
        if (HostState::Crash == i_hostState)
        {
            target = "obmc-host-crash@0.target";
        }

        // If the system is powering off for any reason (ex. we hit a PHYP TI
        // in the graceful power off path), then we want to call the immediate
        // power off target
        if (hostRunningState() == HostRunningState::Stopping)
        {
            trace::inf("system is powering off so no dump will be requested");
            target = "obmc-chassis-hard-poweroff@0.target";
        }

        auto bus = sdbusplus::bus::new_system();
        auto method = bus.new_method_call(
            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
            "org.freedesktop.systemd1.Manager", "StartUnit");

        method.append(target);    // target unit to start
        method.append("replace"); // mode = replace conflicting queued jobs

        bus.call_noreply(method); // start the service
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        trace::err("util::dbus::transitionHost exception");
        std::string traceMsg = std::string(e.what());
        trace::err(traceMsg.c_str());
    }
}

/** @brief Read state of autoRebootEnabled property via dbus */
bool autoRebootEnabled()
{
    // Assume true in case autoRebootEnbabled property is not available
    bool autoReboot = true;

    constexpr auto interface = "xyz.openbmc_project.Control.Boot.RebootPolicy";

    DBusService service; // will find this
    DBusPath path;       // will find this

    // find a dbus object and path that implements the interface
    if (0 == find(interface, path, service))
    {
        DBusValue value;

        // autoreboot policy is implemented as a property
        constexpr auto property = "AutoReboot";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, autoreboot policy is boolean
            autoReboot = std::get<bool>(value);
        }
    }

    return autoReboot;
}

/** @brief Get the running state of the host */
HostRunningState hostRunningState()
{
    // assume not able to get host running state
    HostRunningState host = HostRunningState::Unknown;

    constexpr auto interface = "xyz.openbmc_project.State.Boot.Progress";

    DBusService service;
    DBusPath path;

    // find a dbus object and path that implements the interface
    if (0 == find(interface, path, service))
    {
        DBusValue value;

        // boot progress is implemented as a property
        constexpr auto property = "BootProgress";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, progress is in the vector of strings
            std::string bootProgress(std::get<std::string>(value));

            // convert boot progress to host state
            using BootProgress = sdbusplus::xyz::openbmc_project::State::Boot::
                server::Progress::ProgressStages;

            BootProgress stage = sdbusplus::xyz::openbmc_project::State::Boot::
                server::Progress::convertProgressStagesFromString(bootProgress);

            if ((stage == BootProgress::SystemInitComplete) ||
                (stage == BootProgress::OSStart) ||
                (stage == BootProgress::OSRunning))
            {
                host = HostRunningState::Started;
            }
            else
            {
                host = HostRunningState::NotStarted;
            }
        }
    }

    // See if host in process of powering off when we get NotStarted
    if (host == HostRunningState::NotStarted)
    {
        constexpr auto hostStateInterface = "xyz.openbmc_project.State.Host";
        if (0 == find(hostStateInterface, path, service))
        {
            DBusValue value;

            // current host state is implemented as a property
            constexpr auto stateProperty = "CurrentHostState";

            if (0 == getProperty(hostStateInterface, path, service,
                                 stateProperty, value))
            {
                // return value is a variant, host state is in the vector of
                // strings
                std::string hostState(std::get<std::string>(value));
                if (hostState == "xyz.openbmc_project.State.Host.HostState."
                                 "TransitioningToOff")
                {
                    host = HostRunningState::Stopping;
                }
            }
        }
    }

    return host;
}

/** @brief Read state of dumpPolicyEnabled property via dbus */
bool dumpPolicyEnabled()
{
    // Assume true In case dumpPolicyEnabled property is not available
    bool dumpPolicyEnabled = true;

    constexpr auto interface = "xyz.openbmc_project.Object.Enable";
    constexpr auto path = "/xyz/openbmc_project/dump/system_dump_policy";

    DBusService service; // will find this

    // find a dbus object and path that implements the interface
    if (0 == findService(interface, path, service))
    {
        DBusValue value;

        // autoreboot policy is implemented as a property
        constexpr auto property = "Enabled";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, dump policy enabled is a boolean
            dumpPolicyEnabled = std::get<bool>(value);
        }
    }

    return dumpPolicyEnabled;
}

/** @brief Create a PEL */
uint32_t createPel(const std::string& i_message, const std::string& i_severity,
                   std::map<std::string, std::string>& io_additional,
                   const std::vector<util::FFDCTuple>& i_ffdc)
{
    // CreatePELWithFFDCFiles returns plid
    int plid = 0;

    // Sdbus call specifics
    constexpr auto interface = "org.open_power.Logging.PEL";
    constexpr auto path = "/xyz/openbmc_project/logging";

    // we need to find the service implementing the interface
    util::dbus::DBusService service;

    if (0 == findService(interface, path, service))
    {
        try
        {
            constexpr auto function = "CreatePELWithFFDCFiles";

            // The "Create" method requires manually adding the process ID.
            io_additional["_PID"] = std::to_string(getpid());

            // create dbus method
            auto bus = sdbusplus::bus::new_system();
            sdbusplus::message_t method =
                bus.new_method_call(service.c_str(), path, interface, function);

            // append additional dbus call paramaters
            method.append(i_message, i_severity, io_additional, i_ffdc);

            // using system dbus
            auto response = bus.call(method);

            // reply will be tuple containing bmc log id, platform log id
            std::tuple<uint32_t, uint32_t> reply = {0, 0};

            // parse dbus response into reply
            response.read(reply);
            plid = std::get<1>(reply); // platform log id is tuple "second"
        }
        catch (const sdbusplus::exception::SdBusError& e)
        {
            trace::err("createPel exception");
            trace::err(e.what());
        }
    }

    return plid; // platform log id or 0
}

MachineType getMachineType()
{
    // default to Rainier 2S4U
    MachineType machineType = MachineType::Rainier_2S4U;

    // The return value of the dbus operation is a vector of 4 uint8_ts
    std::vector<uint8_t> ids;

    constexpr auto interface = "com.ibm.ipzvpd.VSBP";

    DBusService service;
    DBusPath path;

    if (0 == find(interface, path, service))
    {
        DBusValue value;

        // Machine ID is given from the "IM" keyword
        constexpr auto property = "IM";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, ID value is a vector of 4 uint8_ts
            ids = std::get<std::vector<uint8_t>>(value);

            // Convert the returned ID value to a hex string to determine
            // machine type. The hex values corresponding to the machine type
            // are defined in /openbmc/openpower-vpd-parser/const.hpp
            // RAINIER_2S4U == 0x50001000
            // RAINIER_2S2U == 0x50001001
            // RAINIER_1S4U == 0x50001002
            // RAINIER_1S2U == 0x50001003
            // EVEREST      == 0x50003000
            try
            {
                // Format the vector into a single hex string to compare to.
                std::string hexId = fmt::format("0x{:02x}{:02x}{:02x}{:02x}",
                                                ids.at(0), ids.at(1), ids.at(2),
                                                ids.at(3));

                std::map<std::string, MachineType> typeMap = {
                    {"0x50001000", MachineType::Rainier_2S4U},
                    {"0x50001001", MachineType::Rainier_2S2U},
                    {"0x50001002", MachineType::Rainier_1S4U},
                    {"0x50001003", MachineType::Rainier_1S2U},
                    {"0x50003000", MachineType::Everest},
                };

                machineType = typeMap.at(hexId);
            }
            catch (const std::out_of_range& e)
            {
                trace::err("Out of range exception caught from returned "
                           "machine ID.");
                for (const auto& id : ids)
                {
                    trace::err("Returned Machine ID value: 0x%x", id);
                }
                throw;
            }
        }
    }
    else
    {
        throw std::invalid_argument(
            "Unable to find dbus service to get machine type.");
    }

    return machineType;
}

/** @brief Get list of state effecter PDRs */
bool getStateEffecterPdrs(std::vector<std::vector<uint8_t>>& pdrList,
                          uint16_t stateSetId)
{
    constexpr auto service = "xyz.openbmc_project.PLDM";
    constexpr auto path = "/xyz/openbmc_project/pldm";
    constexpr auto interface = "xyz.openbmc_project.PLDM.PDR";
    constexpr auto function = "FindStateEffecterPDR";

    constexpr uint16_t PLDM_ENTITY_PROC = 135;

    try
    {
        // create dbus method
        auto bus = sdbusplus::bus::new_default();
        sdbusplus::message_t method = bus.new_method_call(service, path,
                                                          interface, function);

        // append additional method data
        method.append(terminusIdZero, PLDM_ENTITY_PROC, stateSetId);

        // request PDRs
        auto reply = bus.call(method);
        reply.read(pdrList);
    }
    catch (const sdbusplus::exception_t& e)
    {
        trace::err("failed to find state effecter PDRs");
        trace::err(e.what());
        return false;
    }

    return true;
}

/** @brief Get list of state sensor PDRs */
bool getStateSensorPdrs(std::vector<std::vector<uint8_t>>& pdrList,
                        uint16_t stateSetId)
{
    constexpr auto service = "xyz.openbmc_project.PLDM";
    constexpr auto path = "/xyz/openbmc_project/pldm";
    constexpr auto interface = "xyz.openbmc_project.PLDM.PDR";
    constexpr auto function = "FindStateSensorPDR";

    constexpr uint16_t PLDM_ENTITY_PROC = 135;

    try
    {
        // create dbus method
        auto bus = sdbusplus::bus::new_default();
        sdbusplus::message_t method = bus.new_method_call(service, path,
                                                          interface, function);

        // append additional method data
        method.append(terminusIdZero, PLDM_ENTITY_PROC, stateSetId);

        // request PDRs
        auto reply = bus.call(method);
        reply.read(pdrList);
    }
    catch (const sdbusplus::exception_t& e)
    {
        trace::err("failed to find state sensor PDRs");
        trace::err(e.what());
        return false;
    }

    return true;
}

/** @brief Get MCTP instance associated with endpoint */
bool getMctpInstance(uint8_t& mctpInstance, uint8_t Eid)
{
    constexpr auto service = "xyz.openbmc_project.PLDM";
    constexpr auto path = "/xyz/openbmc_project/pldm";
    constexpr auto interface = "xyz.openbmc_project.PLDM.Requester";
    constexpr auto function = "GetInstanceId";

    try
    {
        // create dbus method
        auto bus = sdbusplus::bus::new_default();
        sdbusplus::message_t method = bus.new_method_call(service, path,
                                                          interface, function);

        // append endpoint ID
        method.append(Eid);

        // request MCTP instance ID
        auto reply = bus.call(method);
        reply.read(mctpInstance);
    }
    catch (const sdbusplus::exception_t& e)
    {
        trace::err("get MCTP instance exception");
        trace::err(e.what());
        return false;
    }

    return true;
}

/** @brief Determine if power fault was detected */
bool powerFault()
{
    // power fault based on pgood property
    int32_t pgood = 0; // assume fault or unknown

    constexpr auto interface = "org.openbmc.control.Power";

    DBusService service;
    DBusPath path;

    // find a dbus service and object path that implements the interface
    if (0 == find(interface, path, service))
    {
        DBusValue value;

        // chassis pgood is implemented as a property
        constexpr auto property = "pgood";

        if (0 == getProperty(interface, path, service, property, value))
        {
            // return value is a variant, int32 == 1 for pgood OK
            pgood = std::get<int32_t>(value);
        }
    }

    return pgood != 1 ? true : false; // if not pgood then power fault
}

} // namespace dbus
} // namespace util
