#include "manager.hpp"
#include "utils.hpp"

#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/State/Host/server.hpp>

namespace rules = sdbusplus::bus::match::rules;

namespace // anonymous
{
constexpr auto HOST_CURRENT_STATE = "CurrentHostState";

constexpr auto SYSTEMD_TIME_SERVICE = "org.freedesktop.timedate1";
constexpr auto SYSTEMD_TIME_PATH = "/org/freedesktop/timedate1";
constexpr auto SYSTEMD_TIME_INTERFACE = "org.freedesktop.timedate1";
constexpr auto METHOD_SET_NTP = "SetNTP";
}

namespace phosphor
{
namespace time
{

using namespace phosphor::logging;

const std::set<std::string>
Manager::managedProperties = {PROPERTY_TIME_MODE, PROPERTY_TIME_OWNER};

Manager::Manager(sdbusplus::bus::bus& bus)
    : bus(bus)
{
    using namespace sdbusplus::bus::match::rules;
    hostStateChangeMatch =
        std::make_unique<decltype(hostStateChangeMatch)::element_type>(
            bus,
            propertiesChanged(settings.hostState, settings::hostStateIntf),
            std::bind(std::mem_fn(&Manager::onHostStateChanged),
                      this, std::placeholders::_1));
    settingsMatches.emplace_back(
        bus,
        propertiesChanged(settings.timeOwner, settings::timeOwnerIntf),
        std::bind(std::mem_fn(&Manager::onSettingsChanged),
                  this, std::placeholders::_1));
    settingsMatches.emplace_back(
        bus,
        propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf),
        std::bind(std::mem_fn(&Manager::onSettingsChanged),
          this, std::placeholders::_1));

    checkHostOn();

    // Restore settings from persistent storage
    restoreSettings();

    // Check the settings daemon to process the new settings
    auto mode = getSetting(settings.timeSyncMethod.c_str(),
                           settings::timeSyncIntf,
                           PROPERTY_TIME_MODE);
    auto owner = getSetting(settings.timeOwner.c_str(),
                            settings::timeOwnerIntf,
                            PROPERTY_TIME_OWNER);

    onPropertyChanged(PROPERTY_TIME_MODE, mode);
    onPropertyChanged(PROPERTY_TIME_OWNER, owner);
}

void Manager::addListener(PropertyChangeListner* listener)
{
    // Notify listener about the initial value
    listener->onModeChanged(timeMode);
    listener->onOwnerChanged(timeOwner);

    listeners.insert(listener);
}

void Manager::restoreSettings()
{
    auto mode = utils::readData<std::string>(modeFile);
    if (!mode.empty())
    {
        timeMode = utils::strToMode(mode);
    }
    auto owner = utils::readData<std::string>(ownerFile);
    if (!owner.empty())
    {
        timeOwner = utils::strToOwner(owner);
    }
}

void Manager::checkHostOn()
{
    using Host = sdbusplus::xyz::openbmc_project::State::server::Host;
    auto hostService = utils::getService(bus,
                                         settings.hostState.c_str(),
                                         settings::hostStateIntf);
    auto stateStr = utils::getProperty<std::string>(bus,
                                                    hostService.c_str(),
                                                    settings.hostState.c_str(),
                                                    settings::hostStateIntf,
                                                    HOST_CURRENT_STATE);
    auto state = Host::convertHostStateFromString(stateStr);
    hostOn = (state == Host::HostState::Running);
}

void Manager::onPropertyChanged(const std::string& key,
                                const std::string& value)
{
    if (hostOn)
    {
        // If host is on, set the values as requested time mode/owner.
        // And when host becomes off, notify the listeners.
        setPropertyAsRequested(key, value);
    }
    else
    {
        // If host is off, notify listeners
        if (key == PROPERTY_TIME_MODE)
        {
            setCurrentTimeMode(value);
            onTimeModeChanged(value);
        }
        else if (key == PROPERTY_TIME_OWNER)
        {
            setCurrentTimeOwner(value);
            onTimeOwnerChanged();
        }
    }
}

int Manager::onSettingsChanged(sdbusplus::message::message& msg)
{
    using Interface = std::string;
    using Property = std::string;
    using Value = std::string;
    using Properties = std::map<Property, sdbusplus::message::variant<Value>>;

    Interface interface;
    Properties properties;

    msg.read(interface, properties);

    for(const auto& p : properties)
    {
        onPropertyChanged(p.first, p.second.get<std::string>());
    }

    return 0;
}

void Manager::setPropertyAsRequested(const std::string& key,
                                     const std::string& value)
{
    if (key == PROPERTY_TIME_MODE)
    {
        setRequestedMode(value);
    }
    else if (key == PROPERTY_TIME_OWNER)
    {
        setRequestedOwner(value);
    }
    else
    {
        // The key shall be already the supported one
        using InvalidArgumentError =
            sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
        using namespace xyz::openbmc_project::Common;
        elog<InvalidArgumentError>(
            InvalidArgument::ARGUMENT_NAME(key.c_str()),
            InvalidArgument::ARGUMENT_VALUE(value.c_str()));
    }
}

void Manager::setRequestedMode(const std::string& mode)
{
    requestedMode = mode;
}

void Manager::setRequestedOwner(const std::string& owner)
{
    requestedOwner = owner;
}

void Manager::updateNtpSetting(const std::string& value)
{
    bool isNtp =
        (value == "xyz.openbmc_project.Time.Synchronization.Method.NTP");
    auto method = bus.new_method_call(SYSTEMD_TIME_SERVICE,
                                      SYSTEMD_TIME_PATH,
                                      SYSTEMD_TIME_INTERFACE,
                                      METHOD_SET_NTP);
    method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable
                                 // 'false' meaning no policy-kit

    try
    {
        bus.call_noreply(method);
        log<level::INFO>("Updated NTP setting",
                         entry("ENABLED=%d", isNtp));
    }
    catch (const sdbusplus::exception::SdBusError& ex)
    {
        log<level::ERR>("Failed to update NTP setting",
                        entry("ERR=%s", ex.what()));
    }
}

void Manager::onHostStateChanged(sdbusplus::message::message& msg)
{
    using Interface = std::string;
    using Property = std::string;
    using Value = std::string;
    using Properties = std::map<Property, sdbusplus::message::variant<Value>>;
    using Host = sdbusplus::xyz::openbmc_project::State::server::Host;

    Interface interface;
    Properties properties;

    msg.read(interface, properties);

    for(const auto& p : properties)
    {
        if (p.first == HOST_CURRENT_STATE)
        {
            auto state = Host::convertHostStateFromString(p.second.get<std::string>());
            onHostState(state == Host::HostState::Running);
            break;
        }
    }
}

void Manager::onHostState(bool on)
{
    hostOn = on;
    if (hostOn)
    {
        log<level::INFO>("Changing time settings is *deferred* now");
        return;
    }
    log<level::INFO>("Changing time settings allowed now");
    if (!requestedMode.empty())
    {
        if (setCurrentTimeMode(requestedMode))
        {
            onTimeModeChanged(requestedMode);
        }
        setRequestedMode({}); // Clear requested mode
    }
    if (!requestedOwner.empty())
    {
        if (setCurrentTimeOwner(requestedOwner))
        {
            onTimeOwnerChanged();
        }
        setRequestedOwner({}); // Clear requested owner
    }
}

bool Manager::setCurrentTimeMode(const std::string& mode)
{
    auto newMode = utils::strToMode(mode);
    if (newMode != timeMode)
    {
        log<level::INFO>("Time mode is changed",
                         entry("MODE=%s", mode.c_str()));
        timeMode = newMode;
        utils::writeData(modeFile, mode);
        return true;
    }
    else
    {
        return false;
    }
}

bool Manager::setCurrentTimeOwner(const std::string& owner)
{
    auto newOwner = utils::strToOwner(owner);
    if (newOwner != timeOwner)
    {
        log<level::INFO>("Time owner is changed",
                         entry("OWNER=%s", owner.c_str()));
        timeOwner = newOwner;
        utils::writeData(ownerFile, owner);
        return true;
    }
    else
    {
        return false;
    }
}

void Manager::onTimeModeChanged(const std::string& mode)
{
    for (const auto listener : listeners)
    {
        listener->onModeChanged(timeMode);
    }
    // When time_mode is updated, update the NTP setting
    updateNtpSetting(mode);
}

void Manager::onTimeOwnerChanged()
{
    for (const auto& listener : listeners)
    {
        listener->onOwnerChanged(timeOwner);
    }
}

std::string Manager::getSetting(const char* path,
                                const char* interface,
                                const char* setting) const
{
    std::string settingManager = utils::getService(bus, path, interface);
    return utils::getProperty<std::string>(bus,
                                           settingManager.c_str(),
                                           path,
                                           interface,
                                           setting);
}

}
}
