/*
 *
 *    Copyright (c) 2018 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      Implementation for the Weave Device Layer TimeSyncManager object.
 *
 */

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/internal/ServiceDirectoryManager.h>
#include <Weave/Profiles/time/WeaveTime.h>
#include <Weave/Support/TimeUtils.h>

#include <new>

using namespace ::nl;
using namespace ::nl::Weave;
using namespace ::nl::Weave::Profiles::Time;
using namespace ::nl::Weave::DeviceLayer::Internal;

#if WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC && !WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
#error "CONFIG ERROR: WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC requires WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY to be enabled"
#endif

namespace nl {
namespace Weave {
namespace DeviceLayer {

namespace {

#if WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
SingleSourceTimeSyncClient TimeSyncClient;
#endif

} // unnamed namespace


TimeSyncManager TimeSyncManager::sInstance;

WEAVE_ERROR TimeSyncManager::SetMode(TimeSyncMode newMode)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    VerifyOrExit(newMode > kTimeSyncMode_NotSupported && newMode < kTimeSyncMode_Max, err = WEAVE_ERROR_INVALID_ARGUMENT);

#if !WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC && !WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
    VerifyOrExit(newMode != kTimeSyncMode_Service, err = WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE);
#endif

    mMode = newMode;

    DriveTimeSync();

exit:
    return err;
}

void TimeSyncManager::SetSyncInterval(uint32_t intervalSec)
{
    mSyncIntervalSec = intervalSec;
    DriveTimeSync();
}

bool TimeSyncManager::IsTimeSynchronized()
{
    uint64_t t;
    return System::Layer::GetClock_RealTime(t) == WEAVE_NO_ERROR;
}

WEAVE_ERROR TimeSyncManager::Init()
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

#if WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC
    mServiceDirTimeSyncStartUS = 0;
#endif // WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC

#if WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
    new (&TimeSyncClient) SingleSourceTimeSyncClient();

    err = TimeSyncClient.Init(NULL, &ExchangeMgr);
    SuccessOrExit(err);

    mLastSyncTimeMS = 0;
    mSyncIntervalSec = WEAVE_DEVICE_CONFIG_DEFAULT_TIME_SYNC_INTERVAL;
    mTimeSyncBinding = NULL;
#endif // WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC

#if WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC || WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
    mMode = kTimeSyncMode_Service;
#else
    mMode = kTimeSyncMode_Disabled;
#endif

    ExitNow(err = WEAVE_NO_ERROR); // Avoids warning about unused label

exit:
    return err;
}

void TimeSyncManager::OnPlatformEvent(const WeaveDeviceEvent * event)
{
    if (event->Type == DeviceEventType::kServiceProvisioningChange ||
        (event->Type == DeviceEventType::kServiceConnectivityChange &&
         event->ServiceConnectivityChange.Overall.Result != kConnectivity_NoChange))
    {
        sInstance.DriveTimeSync();
    }
}

#if WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC

void TimeSyncManager::MarkServiceDirRequestStart()
{
    // Mark the local start time of the directory query request using the hi-res clock.
    sInstance.mServiceDirTimeSyncStartUS = System::Layer::GetClock_MonotonicHiRes();
}

void TimeSyncManager::ProcessServiceDirTimeData(uint64_t serverRealTimeMS, uint32_t serverProcessingTimeMS)
{
    // If synchronizing time with the service, and a service directory time sync is in progress...
    if (sInstance.mMode == kTimeSyncMode_Service && sInstance.mServiceDirTimeSyncStartUS != 0)
    {
        // Mark the end time of the request using the hi-res clock.
        uint64_t timeSyncEndUS = System::Layer::GetClock_MonotonicHiRes();

        WeaveLogProgress(DeviceLayer, "Time sync with service directory complete");

        // Use the information from the directory server response to compute an approximation of
        // the current real time.
        uint64_t twoWayTripTimeUS = timeSyncEndUS - sInstance.mServiceDirTimeSyncStartUS - (serverProcessingTimeMS * 1000);
        uint64_t avgOneWayTripTimeUS = twoWayTripTimeUS >> 1;
        uint64_t syncedRealTimeUS = (serverRealTimeMS * 1000) + avgOneWayTripTimeUS;

        // Update the system's real-time clock with the synchronized value.
        sInstance.ApplySynchronizedTime(syncedRealTimeUS);

        // If Weave time server synchronization is also enabled, restart the time server sync
        // interval from this point.
        sInstance.DriveTimeSync();
    }
}

#endif // WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC

void TimeSyncManager::DriveTimeSync()
{
    WEAVE_ERROR err;

#if WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC

    // Make sure there's no time sync in progress.
    CancelTimeSync();

    // If synchronizing time with the service...
    //    AND the system has been service provisioned...
    //    AND the system has service connectivity...
    if (mMode == kTimeSyncMode_Service &&
        ConfigurationMgr().IsServiceProvisioned() &&
        ConnectivityMgr().HaveServiceConnectivity())
    {
        // Compute the amount of time until the next synchronization event.
        uint64_t timeToNextSyncMS = 0;
        if (mLastSyncTimeMS != 0)
        {
            uint64_t nextSyncTimeMS = mLastSyncTimeMS + (mSyncIntervalSec * 1000);
            uint64_t nowMS = System::Layer::GetClock_MonotonicMS();
            if (nowMS < nextSyncTimeMS)
            {
                timeToNextSyncMS = nextSyncTimeMS - nowMS;
            }
        }

        // If synchronization should happen now...
        if (timeToNextSyncMS == 0)
        {
            WeaveLogProgress(DeviceLayer, "Starting time sync with Weave time server");

            // Create and prepare a binding for talking to the time server endpoint.
            // This will result in a callback to HandleTimeServerSyncBindingEvent when
            // the binding is ready to be used.
            mTimeSyncBinding = ExchangeMgr.NewBinding(TimeServiceSync_HandleBindingEvent, NULL);
            VerifyOrExit(mTimeSyncBinding != NULL, err = WEAVE_ERROR_NO_MEMORY);
            err = mTimeSyncBinding->BeginConfiguration()
                    .Target_ServiceEndpoint(WEAVE_DEVICE_CONFIG_WEAVE_TIME_SERVICE_ENDPOINT_ID)
                    .Transport_UDP_WRM()
                    .Exchange_ResponseTimeoutMsec(WEAVE_DEVICE_CONFIG_TIME_SYNC_TIMEOUT)
                    .Security_SharedCASESession()
                    .PrepareBinding();
            SuccessOrExit(err);
        }

        // Otherwise initiate synchronization after an appropriate delay.
        else
        {
            SystemLayer.StartTimer((uint32_t)timeToNextSyncMS, DriveTimeSync, NULL);
        }
    }

#endif // WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC

    ExitNow(err = WEAVE_NO_ERROR); // suppress warning about unused label.

exit:
    if (err != WEAVE_NO_ERROR)
    {
        sInstance.TimeSyncFailed(err, NULL);
    }
}

void TimeSyncManager::CancelTimeSync()
{
#if WEAVE_DEVICE_CONFIG_ENABLE_SERVICE_DIRECTORY_TIME_SYNC
    sInstance.mServiceDirTimeSyncStartUS = 0;
#endif

#if WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
    SystemLayer.CancelTimer(DriveTimeSync, NULL);
    TimeSyncClient.Abort();
    if (mTimeSyncBinding != NULL)
    {
        mTimeSyncBinding->Close();
        mTimeSyncBinding = NULL;
    }
#endif // WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC
}

void TimeSyncManager::ApplySynchronizedTime(uint64_t syncedRealTimeUS)
{
    WEAVE_ERROR err;

    // Only change the system clock if the final time value is valid...
    if (syncedRealTimeUS > (((uint64_t)WEAVE_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) * kMicrosecondsPerSecond))
    {
        bool wasSynchronized = sInstance.IsTimeSynchronized();

        // Attempt to set the system's real time clock.  If successful...
        err = System::Layer::SetClock_RealTime(syncedRealTimeUS);
        if (err == WEAVE_NO_ERROR)
        {
            // If this is the first point at which time is synchronized, post a Time Sync change event.
            if (!wasSynchronized)
            {
                WeaveDeviceEvent event;
                event.Type = DeviceEventType::kTimeSyncChange;
                event.TimeSyncChange.IsTimeSynchronized = true;
                PlatformMgr().PostEvent(&event);
            }
        }
        else
        {
            WeaveLogError(DeviceLayer, "SetClock_RealTime() failed: %s", ErrorStr(err));
        }
    }

    // Update the time from which the next sync interval should be counted.
    sInstance.mLastSyncTimeMS = System::Layer::GetClock_MonotonicMS();
}

void TimeSyncManager::TimeSyncFailed(WEAVE_ERROR reason, Profiles::StatusReporting::StatusReport * statusReport)
{
    WeaveLogError(DeviceLayer, "Time sync failed: %s",
             (reason == WEAVE_ERROR_STATUS_REPORT_RECEIVED && statusReport != NULL)
             ? StatusReportStr(statusReport->mProfileId, statusReport->mStatusCode)
             : ErrorStr(reason));

    // Clear the current state
    CancelTimeSync();

    // Update the time from which the next sync interval should be counted.
    sInstance.mLastSyncTimeMS = System::Layer::GetClock_MonotonicMS();

    // Arrange to try again at the next synchronization interval.
    sInstance.DriveTimeSync();
}

void TimeSyncManager::DriveTimeSync(System::Layer * /* unused */, void * /* unused */, System::Error /* unused */)
{
    sInstance.DriveTimeSync();
}

#if WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC

void TimeSyncManager::TimeServiceSync_HandleBindingEvent(void * appState, ::nl::Weave::Binding::EventType eventType,
            const ::nl::Weave::Binding::InEventParam & inParam, ::nl::Weave::Binding::OutEventParam & outParam)
{
    WEAVE_ERROR err;
    Binding * binding = inParam.Source;

    // If the binding is ready, send a Time Sync request to the timer server.
    if (eventType == Binding::kEvent_BindingReady)
    {
        err = TimeSyncClient.Sync(binding, TimeServiceSync_HandleSyncComplete);
        if (err != WEAVE_NO_ERROR)
        {
            sInstance.TimeSyncFailed(err, NULL);
        }
    }

    // Otherwise handle any failure that occurred during binding preparation.
    else if (eventType == Binding::kEvent_PrepareFailed)
    {
        sInstance.TimeSyncFailed(inParam.PrepareFailed.Reason, inParam.PrepareFailed.StatusReport);
    }

    // Pass all other events to the default handler.
    else
    {
        binding->DefaultEventHandler(appState, eventType, inParam, outParam);
    }
}

void TimeSyncManager::TimeServiceSync_HandleSyncComplete(void * context, WEAVE_ERROR result, int64_t syncedRealTimeUS)
{
    if (result == WEAVE_NO_ERROR)
    {
        WeaveLogProgress(DeviceLayer, "Time sync with time service complete");
        sInstance.ApplySynchronizedTime((uint64_t)syncedRealTimeUS);
        sInstance.DriveTimeSync();
    }
    else
    {
        sInstance.TimeSyncFailed(result, NULL);
    }
}

#endif // WEAVE_DEVICE_CONFIG_ENABLE_WEAVE_TIME_SERVICE_TIME_SYNC

} // namespace DeviceLayer
} // namespace Weave
} // namespace nl
