#define _XOPEN_SOURCE
#include <chrono>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <array>
#include <unistd.h>
#include <assert.h>
#include <sys/timerfd.h>
#include <systemd/sd-event.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-daemon.h>
#include "time-register.hpp"
#include "time-manager.hpp"

// Neeed to do this since its not exported outside of the kernel.
// Refer : https://gist.github.com/lethean/446cea944b7441228298
#ifndef TFD_TIMER_CANCEL_ON_SET
#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
#endif

// Needed to make sure timerfd does not misfire eventhough we set CANCEL_ON_SET
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)

// Used in time-register.c
extern sd_bus_vtable timeServicesVtable[];

Time::Time(const TimeConfig& timeConfig) : config(timeConfig)
{
    // Nothing to do here
}

BmcTime::BmcTime(const TimeConfig& timeConfig) : Time(timeConfig)
{
    // Nothing to do here
}

HostTime::HostTime(const TimeConfig& timeConfig,
                   const std::chrono::microseconds& hostOffset)
    : Time(timeConfig),
      iv_Offset(hostOffset)
{
    // Nothing to do here
}

TimeManager::TimeManager() :
    iv_HostOffset(std::chrono::microseconds(0)),
    iv_UptimeUsec(std::chrono::microseconds(0)),
    iv_EventSource(nullptr),
    iv_Event(nullptr)
{
    assert(setupTimeManager() >= 0);
}

// Needed to be standalone extern "C" to register
// as a callback routine with sd_bus_vtable
int GetTime(sd_bus_message* m, void* userdata,
            sd_bus_error* retError)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return tmgr->getTime(m, userdata, retError);
}

int SetTime(sd_bus_message* m, void* userdata,
            sd_bus_error* retError)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return tmgr->setTime(m, userdata, retError);
}

// Property reader
int getCurrTimeModeProperty(sd_bus* bus, const char* path,
                            const char* interface, const char* property,
                            sd_bus_message* m, void* userdata,
                            sd_bus_error* error)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return sd_bus_message_append(m, "s",
                                 TimeConfig::modeStr(tmgr->config.getCurrTimeMode()));
}

int getCurrTimeOwnerProperty(sd_bus* bus, const char* path,
                             const char* interface, const char* property,
                             sd_bus_message* m, void* userdata,
                             sd_bus_error* error)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return sd_bus_message_append(m, "s",
                                 TimeConfig::ownerStr(tmgr->config.getCurrTimeOwner()));
}

int getReqTimeModeProperty(sd_bus* bus, const char* path,
                           const char* interface, const char* property,
                           sd_bus_message* m, void* userdata,
                           sd_bus_error* error)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return sd_bus_message_append(m, "s",
                                 TimeConfig::modeStr(tmgr->config.getRequestedTimeMode()));
}

int getReqTimeOwnerProperty(sd_bus* bus, const char* path,
                            const char* interface, const char* property,
                            sd_bus_message* m, void* userdata,
                            sd_bus_error* error)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    return sd_bus_message_append(m, "s",
                                 TimeConfig::ownerStr(tmgr->config.getRequestedTimeOwner()));
}

int TimeManager::getTime(sd_bus_message* m, void* userdata,
                         sd_bus_error* retError)
{
    const char* target = nullptr;

    // Extract the target and call respective GetTime
    auto r = sd_bus_message_read(m, "s", &target);
    if (r < 0)
    {
        std::cerr << "Error:" << strerror(-r)
                  <<" reading user time" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_IO_ERROR, "Error reading input");

        return sd_bus_reply_method_error(m, retError);
    }

    if (!strcasecmp(target, "bmc"))
    {
        auto time = BmcTime(config);
        return time.getTime(m, retError);
    }
    else if (!strcasecmp(target, "host"))
    {
        auto time = HostTime(config, iv_HostOffset);
        return time.getTime(m, retError);
    }
    else
    {
        std::cerr << "Error:" << strerror(-r)
                  <<" Invalid Target" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_IO_ERROR, "Valid targets are BMC or HOST");

        return sd_bus_reply_method_error(m, retError);
    }
}

int TimeManager::setTime(sd_bus_message* m, void* userdata,
                         sd_bus_error* retError)
{
    long long int timeInUsec {};

    const char* target = nullptr;
    auto r = sd_bus_message_read(m, "s", &target);
    if (r < 0)
    {
        std::cerr << "Error:" << strerror(-r)
                  <<" reading user time" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_IO_ERROR, "Error reading input");

        return sd_bus_reply_method_error(m, retError);
    }

    if (!strcasecmp(target, "bmc"))
    {
        auto time = BmcTime(config);
        auto r = time.setTime(m, retError);
        if (r < 0)
        {
            // This would have the error populated
            return sd_bus_reply_method_error(m, retError);
        }
    }
    else if (!strcasecmp(target, "host"))
    {
        auto time = HostTime(config, iv_HostOffset);

        auto r = time.setTime(m, retError);
        if (r < 0)
        {
            // This would have the error populated
            return sd_bus_reply_method_error(m, retError);
        }

        if (config.getCurrTimeOwner() == TimeConfig::timeOwners::SPLIT)
        {
            iv_HostOffset = time.getChangedOffset();
            r = config.writeData(cv_HostOffsetFile, iv_HostOffset.count());
            if (r < 0)
            {
                // probably does not make sense to crash on these..
                // The next NTP sync will set things right.
                std::cerr << "Error saving host_offset: "
                          << iv_HostOffset.count() << std::endl;
            }
        }
    }
    return sd_bus_reply_method_return(m, "i", 0);
}

int Time::setTimeOfDay(const std::chrono::microseconds& timeOfDayUsec)
{
    // These 2 are for bypassing some policy
    // checking in the timedate1 service
    auto relative = false;
    auto interactive = false;

    return sd_bus_call_method(config.getDbus(),
                              "org.freedesktop.timedate1",
                              "/org/freedesktop/timedate1",
                              "org.freedesktop.timedate1",
                              "SetTime",
                              nullptr,
                              nullptr,            // timedate1 does not return response
                              "xbb",
                              (int64_t)timeOfDayUsec.count(), //newTimeUsec,
                              relative,        // Time in absolute seconds since epoch
                              interactive);    // bypass polkit checks
}

// Common routine for BMC and HOST Get Time operations
std::chrono::microseconds Time::getBaseTime()
{
    auto currBmcTime = std::chrono::system_clock::now();
    return std::chrono::duration_cast<std::chrono::microseconds>
           (currBmcTime.time_since_epoch());
}

// Accepts the time in microseconds and converts to Human readable format.
std::string Time::convertToStr(const std::chrono::microseconds& timeInUsec)
{
    using namespace std::chrono;

    // Convert this to number of seconds;
    auto timeInSec = duration_cast<seconds>(microseconds(timeInUsec));
    auto time_T = static_cast<std::time_t>(timeInSec.count());

    std::ostringstream timeFormat {};
    timeFormat << std::put_time(std::gmtime(&time_T), "%c %Z");

    auto timeStr = timeFormat.str();
    std::cout << timeStr.c_str() << std::endl;
    return timeStr;
}

// Reads timeofday and returns time string
// and also number of microseconds.
// Ex : Tue Aug 16 22:49:43 2016
int BmcTime::getTime(sd_bus_message *m, sd_bus_error *retError)
{
    std::cout << "Request to get BMC time: ";

    // Get BMC time
    auto timeInUsec = getBaseTime();
    auto timeStr = convertToStr(timeInUsec);
    return sd_bus_reply_method_return(
               m, "sx", timeStr.c_str(), (uint64_t)timeInUsec.count());
}

// Designated to be called by IPMI_GET_SEL time from host
int HostTime::getTime(sd_bus_message *m, sd_bus_error *retError)
{
    using namespace std::chrono;

    std::cout << "Request to get HOST time" << std::endl;

    // Get BMC time and add Host's offset
    // Referencing the iv_hostOffset of TimeManager object
    auto timeInUsec = getBaseTime();
    auto hostTime = timeInUsec.count() + iv_Offset.count();

    auto timeStr = convertToStr(duration_cast<microseconds>
                                (microseconds(hostTime)));

    std::cout << " Host_time_str: [ " << timeStr
              << " ] host_time usec: [ " << hostTime
              << " ] host_offset: [ " << iv_Offset.count()
              << " ] " << std::endl;

    return sd_bus_reply_method_return(m, "sx", timeStr.c_str(),
                                      (uint64_t)hostTime);
    return 0;
}

// Gets the time string and verifies if it conforms to format %Y-%m-%d %H:%M:%S
// and then sets the BMC time. If the input time string does not conform to the
// format, an error message is returned.
int BmcTime::setTime(sd_bus_message *m, sd_bus_error *retError)
{
    tm userTm {};
    const char* userTimeStr = nullptr;

    std::cout << "Request to set BMC time" << std::endl;

    std::cout << "Curr_Mode: " << TimeConfig::modeStr(config.getCurrTimeMode())
              << " Curr_Owner: " << TimeConfig::ownerStr(config.getCurrTimeOwner())
              << std::endl;

    if (config.getCurrTimeMode() == TimeConfig::timeModes::NTP)
    {
        std::cerr << "Can not set time. Mode is NTP" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Current Mode is NTP");

        return -1;
    }

    if(config.getCurrTimeOwner() == TimeConfig::timeOwners::HOST)
    {
        std::cerr << "Can not set time. Owner is HOST" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Current owner is HOST");

        return -1;
    }

    auto r = sd_bus_message_read(m, "s", &userTimeStr);
    if (r < 0)
    {
        std::cerr << "Error:" << strerror(-r)
                  <<" reading user time" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_IO_ERROR, "Error reading input");
        return r;
    }

    std::cout <<" BMC TIME : " << userTimeStr << std::endl;

    // Convert the time string into tm structure
    std::istringstream timeString {};
    timeString.str(userTimeStr);
    timeString >> std::get_time(&userTm, "%Y-%m-%d %H:%M:%S");
    if (timeString.fail())
    {
        std::cerr << "Error: Incorrect time format" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_INVALID_ARGS, "Incorrect time format");
        return -1;
    }

    // Convert the time structure into number of
    // seconds maintained in GMT. Followed the same that is in
    // systemd/timedate1
    auto timeOfDay = timegm(&userTm);
    if (timeOfDay < 0)
    {
        std::cerr <<"Error converting tm to seconds" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Error converting tm to seconds");
        return -1;
    }

    // Set REALTIME and also update hwclock
    auto timeInUsec = std::chrono::microseconds(
                          std::chrono::seconds(timeOfDay));
    r = setTimeOfDay(timeInUsec);
    if (r < 0)
    {
        std::cerr <<"Error: " << strerror(-r)
                  << "setting time on BMC" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Error setting time on BMC");
    }
    return r < 0 ? r : 0;
}

// Gets the time string from IPMI ( which is currently in seconds since epoch )
// and then sets the BMC time / adjusts the offset depending on current owner
// policy.
int HostTime::setTime(sd_bus_message *m, sd_bus_error *retError)
{
    using namespace std::chrono;

    std::cout << "Request to SET Host time" << std::endl;

    std::cout << "Curr_Mode: " << TimeConfig::modeStr(config.getCurrTimeMode())
              << "Curr_Owner: " << TimeConfig::ownerStr(config.getCurrTimeOwner())
              << "host_offset: " << iv_Offset.count() << std::endl;

    if (config.getCurrTimeOwner() == TimeConfig::timeOwners::BMC)
    {
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Current Owner is BMC");
        return -1;
    }

    const char* newHostTime = nullptr;
    auto r = sd_bus_message_read(m, "s", &newHostTime);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  << "reading host time" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_IO_ERROR, "Error reading input");
        return -1;
    }

    // We need to convert the string input to decimal.
    auto hostTimeSec = std::stol(std::string(newHostTime));

    // And then to microseconds
    auto hostTimeUsec = duration_cast<microseconds>(seconds(hostTimeSec));
    std::cout << "setHostTime: HostTimeInUSec: "
              << hostTimeUsec.count() << std::endl;

    if (config.getCurrTimeOwner() == TimeConfig::timeOwners::SPLIT)
    {
        // Adjust the host offset
        auto bmcTimeUsec = duration_cast<microseconds>
                           (system_clock::now().time_since_epoch());

        // We are not doing any time settings in BMC
        std::cout << "Updated: host_time: [  " << hostTimeUsec.count()
                  << " ] host_offset: [ " << iv_Offset.count()
                  << " ] " << std::endl;

        // Communicate the offset back to manager to update needed.
        changedOffset = hostTimeUsec - bmcTimeUsec;

        return 0;
    }

    // We are okay to update time in as long as BMC is not the owner
    r = setTimeOfDay(hostTimeUsec);
    if (r < 0)
    {
        std::cerr <<"Error: " << strerror(-r)
                  << "setting HOST time" << std::endl;
        *retError = SD_BUS_ERROR_MAKE_CONST(
                        SD_BUS_ERROR_FAILED, "Error setting time");
    }

    return r < 0 ? r : 0;
}

// Gets called into by sd_event on an activity seen on sd_bus
int TimeManager::processSdBusMessage(sd_event_source* es, int fd,
                                     uint32_t revents, void* userdata)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    auto r = sd_bus_process(tmgr->getTimeBus(), nullptr);
    if (r < 0)
    {
        std::cerr <<"Error: " << strerror(-r)
                  <<" processing sd_bus message:" << std::endl;
    }
    return r;
}

// Gets called into by sd_event on any time SET event
int TimeManager::processTimeChange(sd_event_source* es, int fd,
                                   uint32_t revents, void* userdata)
{
    using namespace std::chrono;
    std::cout << "BMC time changed" << std::endl;

    auto tmgr = static_cast<TimeManager*>(userdata);

    std::array<char, 64> time {};

    // We are not interested in the data here. Need to read time again .
    // So read until there is something here in the FD
    while (read(fd, time.data(), time.max_size()) > 0);

    std::cout <<" Curr_Mode: " << TimeConfig::modeStr(tmgr->config.getCurrTimeMode())
              << " Curr_Owner : " << TimeConfig::ownerStr(tmgr->config.getCurrTimeOwner())
              << " Host_Offset: " << tmgr->getHostOffset().count() << std::endl;

    // Read the current BMC time and adjust the
    // host time offset if the mode is  SPLIT
    if (tmgr->config.getCurrTimeOwner() == TimeConfig::timeOwners::SPLIT)
    {
        // Delta between REAL and Monotonic.
        auto uptimeUsec = duration_cast<microseconds>
                          (system_clock::now().time_since_epoch() -
                           steady_clock::now().time_since_epoch());

        auto deltaTimeUsec = uptimeUsec - tmgr->getUptimeUsec();

        // If the BMC time goes backwards, then - of - will handle that.
        auto newHostOffset = tmgr->getHostOffset() - deltaTimeUsec;
        tmgr->updateHostOffset(newHostOffset);

        std::cout << " UPDATED HOST_OFFSET: "
                  << tmgr->getHostOffset().count() << std::endl;
        tmgr->updateUptimeUsec(uptimeUsec);

        // Persist this
        auto r = tmgr->config.writeData(TimeManager::cv_HostOffsetFile,
                                        tmgr->getHostOffset().count());
        if (r < 0)
        {
            std::cerr << "Error saving host_offset: "
                      << tmgr->getHostOffset().count() << std::endl;
            return r;
        }
        std::cout << " Updated: Host_Offset: "
                  << tmgr->getHostOffset().count() << std::endl;
    }
    return 0;
}

// Resets iv_HostOffset. Needed when we move away from SPLIT.
int TimeManager::resetHostOffset()
{
    iv_HostOffset = std::chrono::microseconds(0);
    auto r = config.writeData(cv_HostOffsetFile, iv_HostOffset.count());
    config.updateSplitModeFlag(false);
    return r;
}

// Called by sd_event when Pgood is changed in Power
int TimeManager::processPgoodChange(sd_bus_message* m, void* userdata,
                                    sd_bus_error* retError)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    const char* key = nullptr;
    const char* value = nullptr;

    auto newPgood = -1;
    auto r = 0;

    std::cout <<" PGOOD has changed.." << std::endl;

    // input data is "sa{sv}as" and we are just interested in a{sv}
    r = sd_bus_message_skip(m, "s");
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r) <<
                  "skipping interface name in data" << std::endl;
        return r;
    }

    r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<"entering the dictionary" << std::endl;
        return r;
    }

    while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
                "sv")) > 0)
    {
        r = sd_bus_message_read(m, "s", &key);
        if (r < 0)
        {
            std::cerr << "Error: " << strerror(-r)
                      <<" reading the key from dict" << std::endl;
            // Can not continue here since the next
            // enter would result in error anyway
            return r;
        }

        if (!strcmp(key, "pgood"))
        {
            r = sd_bus_message_read(m, "v", "i", &newPgood);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "reading pgood" << std::endl;
                return r;
            }
            r = tmgr->config.updatePropertyVal(key, std::to_string(newPgood));
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "processing pgood" << std::endl;
                return r;
            }
        }
        else
        {
            sd_bus_message_skip(m, "v");
        }
    }
    return 0;
}

// Called by sd_event when Properties are changed in settingsd.
// Interested in changes to 'timeMode', 'timeOwner' and 'use_dhcp_ntp'
int TimeManager::processPropertyChange(sd_bus_message* m, void* userdata,
                                       sd_bus_error* retError)
{
    auto tmgr = static_cast<TimeManager*>(userdata);
    const char* key = nullptr;
    const char* value = nullptr;
    auto r = 0;

    std::cout <<" User Settings have changed.." << std::endl;

    // input data is "sa{sv}as" and we are just interested in a{sv}
    r = sd_bus_message_skip(m, "s");
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r) <<
                  "skipping interface name in data" << std::endl;
        goto finish;
    }

    r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<"entering the dictionary" << std::endl;
        goto finish;
    }

    while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
                "sv")) > 0)
    {
        r = sd_bus_message_read(m, "s", &key);
        if (r < 0)
        {
            std::cerr << "Error: " << strerror(-r)
                      <<" reading the key from dict" << std::endl;
            // Can not continue here since the next
            // enter would result in error anyway
            goto finish;
        }

        if (!strcmp(key, "time_mode"))
        {
            r = sd_bus_message_read(m, "v", "s", &value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "reading timeMode" << std::endl;
                goto finish;
            }
            r = tmgr->config.updatePropertyVal(key, value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "processing timeMode" << std::endl;
                goto finish;
            }
        }
        else if (!strcmp(key, "time_owner"))
        {
            r = sd_bus_message_read(m, "v", "s", &value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "reading timeOwner" << std::endl;
                goto finish;
            }
            r = tmgr->config.updatePropertyVal(key, value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "processing time_owner" << std::endl;
                goto finish;
            }
            else if (tmgr->config.isSplitModeChanged())
            {
                // Must have been a change away from mode SPLIT
                tmgr->resetHostOffset();
            }
        }
        else if (!strcmp(key, "use_dhcp_ntp"))
        {
            r = sd_bus_message_read(m, "v", "s", &value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          <<"reading use_dhcp_ntp" << std::endl;
                goto finish;
            }
            r = tmgr->config.updatePropertyVal(key, value);
            if (r < 0)
            {
                std::cerr << "Error: " << strerror(-r)
                          << "processing dhcp_ntp" << std::endl;
                goto finish;
            }
        }
        else
        {
            sd_bus_message_skip(m, "v");
        }
    }
finish:
    return r;
}

// Sets up callback handlers for activities on :
// 1) user request on SD_BUS
// 2) Time change
// 3) Settings change
// 4) System state change;
int TimeManager::registerCallbackHandlers()
{
    constexpr auto WATCH_SETTING_CHANGE =
        "type='signal',interface='org.freedesktop.DBus.Properties',"
        "path='/org/openbmc/settings/host0',member='PropertiesChanged'";

    constexpr auto WATCH_PGOOD_CHANGE =
        "type='signal',interface='org.freedesktop.DBus.Properties',"
        "path='/org/openbmc/control/power0',member='PropertiesChanged'";

    // Extract the descriptor out of sd_bus construct.
    auto sdBusFd = sd_bus_get_fd(iv_TimeBus);

    auto r = sd_event_add_io(iv_Event, &iv_EventSource, sdBusFd, EPOLLIN,
                             processSdBusMessage, this);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<" adding sd_bus_message handler" << std::endl;
        return r;
    }

    // Choose the MAX time that is possible to aviod mis fires.
    itimerspec maxTime {};
    maxTime.it_value.tv_sec = TIME_T_MAX;

    auto timeFd = timerfd_create(CLOCK_REALTIME, 0);
    if (timeFd < 0)
    {
        std::cerr << "Errorno: " << errno << " creating timerfd" << std::endl;
        return -1;
    }

    r = timerfd_settime(timeFd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
                        &maxTime, nullptr);
    if (r)
    {
        std::cerr << "Errorno: " << errno << "Setting timerfd" << std::endl;
        return -1;
    }

    // Wake me up *only* if someone SETS the time
    r = sd_event_add_io(iv_Event, &iv_EventSource, timeFd, EPOLLIN,
                        processTimeChange, this);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  << "adding time_change handler" << std::endl;
        return r;
    }

    // Watch for property changes in settingsd
    r = sd_bus_add_match(iv_TimeBus, NULL, WATCH_SETTING_CHANGE,
                         processPropertyChange, this);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<" adding property change listener" << std::endl;
        return r;
    }

    // Watch for state change. Only reliable one to count on is
    // state of [pgood]. value of [1] meaning host is powering on / powered
    // on. [0] means powered off.
    r = sd_bus_add_match(iv_TimeBus, NULL, WATCH_PGOOD_CHANGE,
                         processPgoodChange, this);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  << " adding pgood change listener" << std::endl;
    }
    return r;
}

int TimeManager::setupTimeManager()
{
    auto r = sd_bus_default_system(&iv_TimeBus);
    if (r < 0)
    {
        std::cerr << "Error" << strerror(-r)
                  <<" connecting to system bus" << std::endl;
        goto finish;
    }

    r = sd_bus_add_object_manager(iv_TimeBus, NULL, cv_ObjPath);
    if (r < 0)
    {
        std::cerr << "Error" << strerror(-r)
                  <<" adding object manager" << std::endl;
        goto finish;
    }

    std::cout <<"Registering dbus methods" << std::endl;
    r = sd_bus_add_object_vtable(iv_TimeBus,
                                 NULL,
                                 cv_ObjPath,
                                 cv_BusName,
                                 timeServicesVtable,
                                 this);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<" adding timer services vtable" << std::endl;
        goto finish;
    }

    // create a sd_event object and add handlers
    r = sd_event_default(&iv_Event);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  <<"creating an sd_event" << std::endl;
        goto finish;
    }

    // Handlers called by sd_event when an activity
    // is observed in event loop
    r = registerCallbackHandlers();
    if (r < 0)
    {
        std::cerr << "Error setting up callback handlers" << std::endl;
        goto finish;
    }

    // Need to do this here since TimeConfig may update the necessary owners
    r = config.processInitialSettings(iv_TimeBus);
    if (r < 0)
    {
        std::cerr << "Error setting up configuration params" << std::endl;
        goto finish;
    }

    // Read saved values from previous run
    r = readPersistentData();
    if (r < 0)
    {
        std::cerr << "Error reading persistent data" << std::endl;
        goto finish;
    }

    // Claim the bus
    r = sd_bus_request_name(iv_TimeBus, cv_BusName, 0);
    if (r < 0)
    {
        std::cerr << "Error: " << strerror(-r)
                  << "acquiring service name" << std::endl;
        goto finish;
    }
finish:
    if (r < 0)
    {
        iv_EventSource = sd_event_source_unref(iv_EventSource);
        iv_Event = sd_event_unref(iv_Event);
    }
    return r;
}

int TimeManager::readPersistentData()
{
    using namespace std::chrono;

    // Get current host_offset
    // When we reach here, TimeConfig would have been populated and would have
    // applied the owner to SPLIT *if* the system allowed it. So check if we
    // moved away from SPLIT and if so, make offset:0
    if (config.isSplitModeChanged())
    {
        iv_HostOffset = microseconds(0);
        auto r = config.writeData(cv_HostOffsetFile, iv_HostOffset.count());
        if (r < 0)
        {
            std::cerr <<" Error saving offset to file" << std::endl;
            return r;
        }
    }
    else
    {
        auto hostTimeOffset = config.readData<long long int>(cv_HostOffsetFile);
        iv_HostOffset = microseconds(hostTimeOffset);
        std::cout <<"Last known host_offset:" << hostTimeOffset << std::endl;
    }

    //How long was the FSP up prior to 'this' start
    iv_UptimeUsec = duration_cast<microseconds>
                    (system_clock::now().time_since_epoch() -
                     steady_clock::now().time_since_epoch());
    if (iv_UptimeUsec.count() < 0)
    {
        std::cerr <<"Error reading uptime" << std::endl;
        return -1;
    }
    std::cout <<"Initial Uptime Usec: "
              << iv_UptimeUsec.count() << std::endl;
    return 0;
}

// Forever loop
int TimeManager::waitForClientRequest()
{
    return sd_event_loop(iv_Event);
}

int main(int argc, char* argv[])
{
    auto tmgr = std::make_unique<TimeManager>();

    // Wait for the work
    auto r = tmgr->waitForClientRequest();

    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
