#pragma once

#include "types.hpp"
#include "property_change_listener.hpp"
#include "settings.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>

#include <set>
#include <string>

namespace phosphor
{
namespace time
{

/** @class Manager
 *  @brief The manager to handle OpenBMC time.
 *  @details It registers various time related settings and properties signals
 *  on DBus and handle the changes.
 *  For certain properties it also notifies the changed events to listeners.
 */
class Manager
{
    public:
        friend class TestManager;

        explicit Manager(sdbusplus::bus::bus& bus);
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = delete;
        Manager& operator=(Manager&&) = delete;
        ~Manager() = default;

        /** @brief Add a listener that will be called
          * when property is changed
         **/
        void addListener(PropertyChangeListner* listener);

    private:
        /** @brief Persistent sdbusplus DBus connection */
        sdbusplus::bus::bus& bus;

        /** @brief The match of settings property change */
        std::vector<sdbusplus::bus::match::match> settingsMatches;

        /** @brief The match of host state change */
        std::unique_ptr<sdbusplus::bus::match::match> hostStateChangeMatch;

        /** @brief The container to hold all the listeners */
        std::set<PropertyChangeListner*> listeners;

        /** @brief Settings objects of intereset */
        settings::Objects settings;

        /** @brief The value to indicate if host is on */
        bool hostOn = false;

        /** @brief The requested time mode when host is on*/
        std::string requestedMode;

        /** @brief The requested time owner when host is on*/
        std::string requestedOwner;

        /** @brief The current time mode */
        Mode timeMode;

        /** @brief The current time owner */
        Owner timeOwner;

        /** @brief Restore saved settings */
        void restoreSettings();

        /** @brief Check if host is on and update hostOn variable */
        void checkHostOn();

        /** @brief Get setting from settingsd service
         *
         * @param[in] path - The dbus object path
         * @param[in] interface - The dbus interface
         * @param[in] setting - The string of the setting
         *
         * @return The setting value in string
         */
        std::string getSetting(const char* path,
                               const char* interface,
                               const char* setting) const;

        /** @brief Set current time mode from the time mode string
         *
         * @param[in] mode - The string of time mode
         *
         * @return - true if the mode is updated
         *           false if it's the same as before
         */
        bool setCurrentTimeMode(const std::string& mode);

        /** @brief Set current time owner from the time owner string
         *
         * @param[in] owner - The string of time owner
         *
         * @return - true if the owner is updated
         *           false if it's the same as before
         */
        bool setCurrentTimeOwner(const std::string& owner);

        /** @brief Called on time mode is changed
         *
         * Notify listeners that time mode is changed and update ntp setting
         *
         * @param[in] mode - The string of time mode
         */
        void onTimeModeChanged(const std::string& mode);

        /** @brief Called on time owner is changed
         *
         * Notify listeners that time owner is changed
         */
        void onTimeOwnerChanged();

        /** @brief Callback to handle change in a setting
         *
         *  @param[in] msg - sdbusplus dbusmessage
         *
         *  @return 0 on success, < 0 on failure.
         */
        int onSettingsChanged(sdbusplus::message::message& msg);

        /** @brief Notified on settings property changed
         *
         * @param[in] key - The name of property that is changed
         * @param[in] value - The value of the property
         */
        void onPropertyChanged(const std::string& key,
                               const std::string& value);

        /** @brief Notified on host state has changed
         *
         * @param[in] msg - sdbusplus dbusmessage
         */
        void onHostStateChanged(sdbusplus::message::message& msg);

        /** @brief Notified on host state has changed
         *
         * @param[in] on - Indicate if the host is on or off
         */
        void onHostState(bool on);

        /** @brief Set the property as requested time mode/owner
         *
         * @param[in] key - The property name
         * @param[in] value - The property value
         */
        void setPropertyAsRequested(const std::string& key,
                                    const std::string& value);

        /** @brief Set the current mode to user requested one
         *  if conditions allow it
         *
         * @param[in] mode - The string of time mode
         */
        void setRequestedMode(const std::string& mode);

        /** @brief Set the current owner to user requested one
         *  if conditions allow it
         *
         * @param[in] owner - The string of time owner
         */
        void setRequestedOwner(const std::string& owner);

        /** @brief Update the NTP setting to systemd time service
         *
         * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL"
         */
        void updateNtpSetting(const std::string& value);

        /** @brief The static function called on settings property changed
         *
         * @param[in] msg - Data associated with subscribed signal
         * @param[in] userData - Pointer to this object instance
         * @param[out] retError  - Not used but required with signal API
         */
        static int onPropertyChanged(sd_bus_message* msg,
                                     void* userData,
                                     sd_bus_error* retError);

        /** @brief The string of time mode property */
        static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod";

        /** @brief The string of time owner property */
        static constexpr auto PROPERTY_TIME_OWNER = "TimeOwner";

        using Updater = std::function<void(const std::string&)>;

        /** @brief Map the property string to functions that shall
         *  be called when the property is changed
         */
        const std::map<std::string, Updater> propertyUpdaters =
        {
            {PROPERTY_TIME_MODE, std::bind(&Manager::setCurrentTimeMode,
                                           this, std::placeholders::_1)},
            {PROPERTY_TIME_OWNER, std::bind(&Manager::setCurrentTimeOwner,
                                            this, std::placeholders::_1)}
        };

        /** @brief The properties that manager shall notify the
         *  listeners when changed
         */
        static const std::set<std::string> managedProperties;

        /** @brief The map that maps the string to Owners */
        static const std::map<std::string, Owner> ownerMap;

        /** @brief The file name of saved time mode */
        static constexpr auto modeFile = "/var/lib/obmc/saved_time_mode";

        /** @brief The file name of saved time owner */
        static constexpr auto ownerFile = "/var/lib/obmc/saved_time_owner";
};

}
}
