#include <map>
#include <systemd/sd-bus.h>
#include <sdbusplus/bus/match.hpp>
#include "settings.hpp"

/** @class TimeConfig
 *  @brief Maintains various time modes and time owners.
 */
class TimeConfig
{
public:
    /** @brief Supported time modes
     *  NTP     Time sourced by Network Time Server
     *  MANUAL  User of the system need to set the time
     */
    enum class timeModes
    {
        NTP,
        MANUAL
    };

    /** @brief Supported time owners
     *  BMC     Time source may be NTP or MANUAL but it has to be set natively
     *          on the BMC. Meaning, host can not set the time. What it also
     *          means is that when BMC gets IPMI_SET_SEL_TIME, then its ignored.
     *          similarly, when BMC gets IPMI_GET_SEL_TIME, then the BMC's time
     *          is returned.
     *
     *  HOST    Its only IPMI_SEL_SEL_TIME that will set the time on BMC.
     *          Meaning, IPMI_GET_SEL_TIME and request to get BMC time will
     *          result in same value.
     *
     *  SPLIT   Both BMC and HOST will maintain their individual clocks but then
     *          the time information is stored in BMC. BMC can have either NTP
     *          or MANUAL as it's source of time and will set the time directly
     *          on the BMC. When IPMI_SET_SEL_TIME is received, then the delta
     *          between that and BMC's time is calculated and is stored.
     *          When BMC reads the time, the current time is returned.
     *          When IPMI_GET_SEL_TIME is received, BMC's time is retrieved and
     *          then the delta offset is factored in prior to returning.
     *
     *  BOTH:   BMC's time is set with whoever that sets the time. Similarly,
     *          BMC's time is returned to whoever that asks the time.
     */
    enum class timeOwners
    {
        BMC,
        HOST,
        SPLIT,
        BOTH
    };

    // Do not have a usecase of copying this object so disable
    TimeConfig();
    ~TimeConfig() = default;
    TimeConfig(const TimeConfig&) = delete;
    TimeConfig& operator=(const TimeConfig&) = delete;
    TimeConfig(TimeConfig&&) = delete;
    TimeConfig& operator=(TimeConfig&&) = delete;

    inline auto getCurrTimeMode() const
    {
        return iv_CurrTimeMode;
    }

    inline auto getCurrTimeOwner() const
    {
        return iv_CurrTimeOwner;
    }

    inline auto getRequestedTimeMode() const
    {
        return iv_RequestedTimeMode;
    }

    inline auto getRequestedTimeOwner() const
    {
        return iv_RequestedTimeOwner;
    }

    inline auto isSplitModeChanged() const
    {
        return iv_SplitModeChanged;
    }

    inline void updateSplitModeFlag(const bool& value)
    {
        iv_SplitModeChanged = value;
    }

    inline sd_bus* getDbus() const
    {
        return iv_dbus;
    }

    /** brief Generic file reader used to read time mode,
     *  time owner, host time,  host offset and useDhcpNtp
     *
     *  @param[in] filename - Name of file where data is preserved.
     *  @return             - File content
     */
    template <typename T>
    T readData(const char* fileName)
    {
        T data = T();
        if(std::ifstream(fileName))
        {
            std::ifstream file(fileName, std::ios::in);
            file >> data;
            file.close();
        }
        return data;
    }

    /** @brief Generic file writer used to write time mode,
     *  time owner, host time,  host offset and useDhcpNtp
     *
     *  @param[in] filename - Name of file where data is preserved.
     *  @param[in] data     - Data to be written to file
     *  @return             - 0 for now. But will be changed to raising
     *                      - Exception
     */
    template <typename T>
    auto writeData(const char* fileName, T&& data)
    {
        std::ofstream file(fileName, std::ios::out);
        file << data;
        file.close();
        return 0;
    }

    /** @brief Reads saved data and populates below properties
     *  - Current Time Mode
     *  - Current Time Owner
     *  - Whether to use NTP settings given by DHCP
     *  - Last known host offset
     *
     *  @param[in] dbus -  Handler to sd_bus used by time manager
     *
     *  @return         -  < 0 for failure and others for success
     */
    int processInitialSettings(sd_bus* dbus);

    /** @brief Accepts time mode string, returns the equivalent enum
     *
     *  @param[in] timeModeStr - Current Time Mode in string
     *
     *  @return                - Equivalent ENUM
     *                         - Input : "NTP", Output: timeModes::NTP
     */
    static timeModes getTimeMode(const char* timeModeStr);

    /** @brief Accepts timeMode enum and returns it's string equivalent
     *
     *  @param[in] timeMode - Current Time Mode Enum
     *
     *  @return             - Equivalent string
     *                      - Input : timeModes::NTP, Output : "NTP"
     */
    static const char* modeStr(const timeModes timeMode);

    /** @brief Accepts timeOwner string and returns it's equivalent enum
     *
     *  @param[in] timeOwnerStr - Current Time Owner in string
     *
     *  @return              - Equivalent ENUM
     *                       - Input : "BMC", output : timeOwners::BMC
     */
    static timeOwners getTimeOwner(const char* timeOwnerStr);

    /** @brief Accepts timeOwner enum and returns it's string equivalent
     *
     *  @param[in] timeOwner - Current Time Mode Enum
     *
     *  @return              - Equivalent string
     *                       - Input : timeOwners::BMC, Output : "BMC"
     */
    static const char* ownerStr(const timeOwners timeOwner);

    /** @brief Gets called when the settings property changes.
     *  Walks the map and then applies the changes
     *
     *  @param[in] key   - Name of the property
     *  @param[in] value - Value
     *
     *  @return              - < 0 on failure, success otherwise
     */
    int updatePropertyVal(const char* key, const std::string& value);

    // Acts on the time property changes / reads initial property
    using READER = std::string (TimeConfig::*) (const char*);
    using UPDATER = int (TimeConfig::*) (const std::string&);
    using FUNCTOR = std::tuple<READER, UPDATER>;

    // Most of this is statically constructed and PGOOD is added later.
    static std::map<std::string, FUNCTOR> iv_TimeParams;

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

private:
    // Bus initialised by manager on a call to process initial settings
    sd_bus *iv_dbus;

    /** @brief 'Requested' is what is asked by user in settings
     * 'Current' is what the TimeManager is really using since its not
     *  possible to apply the mode and owner as and when the user updates
     *  Settings. They are only applied when the system power is off.
     */
    timeModes  iv_CurrTimeMode;
    timeModes  iv_RequestedTimeMode;

    timeOwners iv_CurrTimeOwner;
    timeOwners iv_RequestedTimeOwner;

    /** @brief One of the entry in .network file indicates whether the
     *  systemd-timesyncd should use the NTP server list that are sent by DHCP
     *  server or not. If the value is 'yes', then NTP server list sent by DHCP
     *  are used. else entries that are configured statically with NTP= are used
     */
    std::string iv_CurrDhcpNtp;

    /** @brief Dictated by state of pgood. When the pgood value is 'zero', then
     *  its an indication that we are okay to apply any pending Mode / Owner
     *  values. Meaning, Current will be updated with what is in Requested.
     */
    bool        iv_SettingChangeAllowed;

    // Needed to nudge Time Manager to reset offset
    bool        iv_SplitModeChanged;

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

    /** @brief sbdbusplus match objects */
    std::vector<sdbusplus::bus::match_t> settingsMatches;

    static constexpr auto cv_TimeModeFile = "/var/lib/obmc/saved_timeMode";
    static constexpr auto cv_TimeOwnerFile = "/var/lib/obmc/saved_timeOwner";
    static constexpr auto cv_DhcpNtpFile = "/var/lib/obmc/saved_dhcpNtp";

    /** @brief Wrapper that looks up in the mapper service for a given
     *  object path and returns the service name
     *
     *  @param[in] objpath - dbus object path
     *
     *  @return            - unique_ptr holding service name.
     *                     - Caller needs to validate if its populated
     */
    std::unique_ptr<char> getProvider(const char* objPath);

    /** @brief Helper function for processInitialSettings.
     *  Reads saved data and populates below properties. Only the values are
     *  read from the file system. but it will not take the action on those.
     *  Actions on these are taken by processInitialSettings
     *
     *  - Current Time Mode
     *  - Current Time Owner
     *  - Whether to use NTP settings given by DHCP
     *  - Current Pgood state
     *
     *  @return         -  < 0 for failure and success on others
     */
    int readPersistentData();

    /** @brief Updates the 'ntp' field in systemd/timedate1,
     *  which enables / disables NTP syncing
     *
     *  @param[in] newTimeMode - Time Mode Enum
     *
     *  @return                - < 0 on failure and success on others
     */
    int modifyNtpSettings(const timeModes& newTimeMode);

    /** @brief Accepts system setting parameter and returns its value
     *
     *  @param[in] key - Name of the property
     *
     *  @return        - Value as string
     */
    std::string getSystemSettings(const char* key);

    /** @brief Returns the time owner setting
     *
     *  @param[in] path - Time owner setting object path
     *
     *  @return        - Value as string
     */
    std::string getTimeOwnerSetting(const char* path);

    /** @brief Returns the time sync method setting
     *
     *  @param[in] path - Time sync method setting object path
     *
     *  @return        - Value as string
     */
    std::string getTimeSyncMethodSetting(const char* path);

    /** @brief Reads the data hosted by /org/openbmc/control/power0
     *
     *  @param[in] key - Name of the property
     *
     *  @return        - Value as string
     */
    std::string getPowerSetting(const char* key);

    /** @brief Accepts Mode string and applies only if conditions allow it.
     *
     *  @param[in] newModeStr - Requested Time Mode
     *
     *  @return               - < 0 on failure, success otherwise
     */
    int updateTimeMode(const std::string& newModeStr);

    /** @brief Accepts Ownere string and applies only if conditions allow it.
     *
     *  @param[in] newOwnerStr - Requested Time Owner
     *
     *  @return               - < 0 on failure, success otherwise
     */

    int updateTimeOwner(const std::string& newownerStr);

    /** @brief Updates .network file with UseNtp= provided by NetworkManager
     *
     *  @param[in] useDhcpNtp - will be 'yes' or 'no'
     *
     *  @return               - < 0 on failure, success otherwise
     */
    int updateNetworkSettings(const std::string& useDhcpNtp);

    /** @brief Accepts current pgood value and then updates any pending mode
     *  or owner requests
     *
     *  @param[in] useDhcpNtp - will be 'yes' or 'no'
     *
     *  @return               - < 0 on failure, success otherwise
     */
    int processPgoodChange(const std::string& newPgood);
};
