#include "system_configuration.hpp"

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

namespace phosphor
{
namespace network
{

static constexpr char HOSTNAMED_SVC[] = "org.freedesktop.hostname1";
static constexpr char HOSTNAMED_OBJ[] = "/org/freedesktop/hostname1";
static constexpr char HOSTNAMED_INTF[] = "org.freedesktop.hostname1";

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using Argument = xyz::openbmc_project::Common::InvalidArgument;

static constexpr char propMatch[] =
    "type='signal',sender='org.freedesktop.hostname1',"
    "path='/org/freedesktop/hostname1',"
    "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',"
    "arg0='org.freedesktop.hostname1'";

SystemConfiguration::SystemConfiguration(
    stdplus::PinnedRef<sdbusplus::bus_t> bus, stdplus::const_zstring objPath) :
    Iface(bus, objPath.c_str(), Iface::action::defer_emit), bus(bus),
    hostnamePropMatch(
        bus, propMatch,
        [sc = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) {
            std::string intf;
            std::unordered_map<std::string, std::variant<std::string>> values;
            try
            {
                m.read(intf, values);
                auto it = values.find("Hostname");
                if (it == values.end())
                {
                    return;
                }
                sc.get().Iface::hostName(std::get<std::string>(it->second));
            }
            catch (const std::exception& e)
            {
                lg2::error("Hostname match parsing failed: {ERROR}", "ERROR",
                           e);
            }
        })
{
    try
    {
        std::variant<std::string> name;
        auto req =
            bus.get().new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ,
                                      "org.freedesktop.DBus.Properties", "Get");

        req.append(HOSTNAMED_INTF, "Hostname");
        auto reply = req.call();
        reply.read(name);
        SystemConfigIntf::hostName(std::get<std::string>(name), true);
    }
    catch (const std::exception& e)
    {
        lg2::error("Failed to get hostname: {ERROR}", "ERROR", e);
    }

    emit_object_added();
}

std::string SystemConfiguration::hostName(std::string name)
{
    if (SystemConfigIntf::hostName() == name)
    {
        return name;
    }
    try
    {
        auto method = bus.get().new_method_call(
            HOSTNAMED_SVC, HOSTNAMED_OBJ, HOSTNAMED_INTF, "SetStaticHostname");
        method.append(name, /*interactive=*/false);
        method.call();
        return SystemConfigIntf::hostName(std::move(name));
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        lg2::error("Failed to set hostname {HOSTNAME}: {ERROR} ", "HOSTNAME",
                   name, "ERROR", e);
        auto dbusError = e.get_error();
        if ((dbusError != nullptr) &&
            (strcmp(dbusError->name,
                    "org.freedesktop.DBus.Error.InvalidArgs") == 0))
        {
            elog<InvalidArgument>(Argument::ARGUMENT_NAME("Hostname"),
                                  Argument::ARGUMENT_VALUE(name.c_str()));
        }
    }
    return SystemConfigIntf::hostName();
}

} // namespace network
} // namespace phosphor
