// Copyright 2021 The Pigweed Authors
//
// 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
//
//     https://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.

#include "pw_chrono/system_timer.h"

#include <algorithm>
#include <mutex>

#include "FreeRTOS.h"
#include "pw_assert/check.h"
#include "pw_chrono_freertos/system_clock_constants.h"
#include "task.h"
#include "timers.h"

namespace pw::chrono {
namespace {

using State = backend::NativeSystemTimer::State;

// Instead of adding targeted locks to each instance, simply use the global
// scheduler critical section lock.
class SchedulerLock {
 public:
  static void lock() { vTaskSuspendAll(); }
  static void unlock() { xTaskResumeAll(); }
};
SchedulerLock global_timer_lock;

void HandleTimerCallback(TimerHandle_t timer_handle) {
  // The FreeRTOS timer service is always handled by a thread, ergo to ensure
  // this API is threadsafe we simply disable task switching.
  std::unique_lock lock(global_timer_lock);

  // Because the timer control block, AKA what the timer handle points at, is
  // the first member of the NativeSystemTimer struct we play a trick to cheaply
  // get the native handle reference.
  backend::NativeSystemTimer& native_type =
      *reinterpret_cast<backend::NativeSystemTimer*>(timer_handle);

  PW_CHECK_UINT_EQ(xTimerIsTimerActive(timer_handle),
                   pdFALSE,
                   "The timer is still active while being executed");

  if (native_type.state == State::kCancelled) {
    // Do nothing, we were invoked while the stop command was in the queue.
    return;
  }

  const SystemClock::duration time_until_deadline =
      native_type.expiry_deadline - SystemClock::now();
  if (time_until_deadline <= SystemClock::duration::zero()) {
    // We have met the deadline, cancel the current state and execute the user's
    // callback. Note we cannot update the state later as the user's callback
    // may alter the desired state through the Invoke*() API.
    native_type.state = State::kCancelled;

    // Release the scheduler lock once we won't modify native_state any further.
    lock.unlock();
    native_type.user_callback(native_type.expiry_deadline);
    return;
  }

  // We haven't met the deadline yet, reschedule as far out as possible.
  // Note that this must be > SystemClock::duration::zero() based on the
  // conditional above.
  const SystemClock::duration period =
      std::min(pw::chrono::freertos::kMaxTimeout, time_until_deadline);
  PW_CHECK_UINT_EQ(
      xTimerChangePeriod(
          &native_type.tcb, static_cast<TickType_t>(period.count()), 0),
      pdPASS,
      "Timer command queue overflowed");
  PW_CHECK_UINT_EQ(xTimerStart(&native_type.tcb, 0),
                   pdPASS,
                   "Timer command queue overflowed");
}

// FreeRTOS requires a timer to have a non-zero period.
constexpr SystemClock::duration kMinTimerPeriod = SystemClock::duration(1);
constexpr TickType_t kInvalidPeriod = kMinTimerPeriod.count();
constexpr UBaseType_t kOneShotMode = pdFALSE;  // Do not use auto reload.

}  // namespace

#if configUSE_TIMERS != 1
#error \
    "Backend requires your FreeRTOS configuration to have configUSE_TIMERS == 1"
#endif

#if configSUPPORT_STATIC_ALLOCATION != 1
#error \
    "Backend requires your FreeRTOS configuration to have configSUPPORT_STATIC_ALLOCATION == 1"
#endif

SystemTimer::SystemTimer(ExpiryCallback callback)
    : native_type_{.tcb{},
                   .state = State::kCancelled,
                   .expiry_deadline = SystemClock::time_point(),
                   .user_callback = std::move(callback)} {
  // Note that timer "creation" is not enqueued through the command queue and
  // is ergo safe to do before the scheduler is running.
  const TimerHandle_t handle =
      xTimerCreateStatic("",  // "pw::chrono::SystemTimer",
                         kInvalidPeriod,
                         kOneShotMode,
                         this,
                         HandleTimerCallback,
                         &native_type_.tcb);

  // This should never fail since the pointer provided was not null and it
  // should return a pointer to the StaticTimer_t.
  PW_DCHECK_PTR_EQ(handle, &native_type_.tcb);
}

SystemTimer::~SystemTimer() {
  Cancel();

  // WARNING: This enqueues the request to delete the timer through a queue, it
  // does not synchronously delete and disable the timer here! This means that
  // if the timer is about to expire and the timer service thread is a lower
  // priority that it may use the native_type_ after it is free'd.
  PW_CHECK_UINT_EQ(pdPASS,
                   xTimerDelete(&native_type_.tcb, 0),
                   "Timer command queue overflowed");

  // In case the timer is still active as warned above, busy yield loop until it
  // has been removed. Note that this is safe before the scheduler has been
  // started because the timer cannot have been added to the queue yet and ergo
  // it shouldn't attempt to yield.
  while (xTimerIsTimerActive(&native_type_.tcb)) {
    taskYIELD();
  }
}

void SystemTimer::InvokeAt(SystemClock::time_point timestamp) {
  // The FreeRTOS timer service is always handled by a thread, ergo to ensure
  // this API is threadsafe we simply disable task switching.
  std::lock_guard lock(global_timer_lock);

  // We don't want to call Cancel which would enqueue a stop command instead of
  // synchronously updating the state. Instead we update the expiry deadline
  // and update the state where the one shot only fires if the expiry deadline
  // is exceeded and the callback is executed once.
  native_type_.expiry_deadline = timestamp;

  // Schedule the timer as far out as possible. Note that the timeout might be
  // clamped and it may be rescheduled internally.
  const SystemClock::duration time_until_deadline =
      timestamp - SystemClock::now();
  const SystemClock::duration period = std::clamp(
      kMinTimerPeriod, time_until_deadline, pw::chrono::freertos::kMaxTimeout);

  PW_CHECK_UINT_EQ(
      xTimerChangePeriod(
          &native_type_.tcb, static_cast<TickType_t>(period.count()), 0),
      pdPASS,
      "Timer command queue overflowed");

  // Don't enqueue the start multiple times, schedule it once and let the
  // callback cancel.
  if (native_type_.state == State::kCancelled) {
    PW_CHECK_UINT_EQ(xTimerStart(&native_type_.tcb, 0),
                     pdPASS,
                     "Timer command queue overflowed");
    native_type_.state = State::kScheduled;
  }
}

void SystemTimer::Cancel() {
  // The FreeRTOS timer service is always handled by a thread, ergo to ensure
  // this API is threadsafe we simply disable task switching.
  std::lock_guard lock(global_timer_lock);

  // The stop command may not be executed until later in case we're in a
  // critical section. For this reason update the internal state in case the
  // callback gets invoked.
  //
  // Note that xTimerIsTimerActive cannot be used here as the timer service
  // daemon may be a lower priority and ergo may still execute the callback
  // after Cancel() was invoked. This is because a single expired timer may be
  // processed before the entire command queue is emptied.
  native_type_.state = State::kCancelled;

  PW_CHECK_UINT_EQ(xTimerStop(&native_type_.tcb, 0),
                   pdPASS,
                   "Timer command queue overflowed");
}

}  // namespace pw::chrono
