#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::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
