// Copyright 2022 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_sync/timed_thread_notification.h"

#include <chrono>
#include <optional>

#include "FreeRTOS.h"
#include "pw_chrono/system_clock.h"
#include "pw_thread/non_portable_test_thread_options.h"
#include "pw_thread/sleep.h"
#include "pw_thread/thread.h"
#include "pw_thread/thread_core.h"
#include "pw_unit_test/framework.h"
#include "task.h"

namespace pw::sync::freertos {
namespace {

using pw::chrono::SystemClock;
using pw::thread::Thread;

}  // namespace

// These tests are targeted specifically to verify interactions between suspend
// and being blocked on direct task notifications and how they impact usage of
// the FreeRTOS optimized TimedThreadNotification backend.
#if INCLUDE_vTaskSuspend == 1

class TimedNotificationAcquirer : public thread::ThreadCore {
 public:
  void WaitUntilRunning() { started_notification_.acquire(); }
  void Release() { unblock_notification_.release(); }
  void WaitUntilFinished() { finished_notification_.acquire(); }
  std::optional<SystemClock::time_point> notified_time() const {
    return notified_time_;
  }
  TaskHandle_t task_handle() const { return task_handle_; }

 private:
  void Run() final {
    task_handle_ = xTaskGetCurrentTaskHandle();
    started_notification_.release();
    if (unblock_notification_.try_acquire_until(
            SystemClock::TimePointAfterAtLeast(std::chrono::hours(42)))) {
      notified_time_ = SystemClock::now();
    }
    finished_notification_.release();
  }

  TaskHandle_t task_handle_;
  TimedThreadNotification started_notification_;
  TimedThreadNotification unblock_notification_;
  ThreadNotification finished_notification_;
  std::optional<SystemClock::time_point> notified_time_;
};

TEST(TimedThreadNotification, AcquireWithoutSuspend) {
  TimedNotificationAcquirer notification_acquirer;
  // TODO: b/290860904 - Replace TestOptionsThread0 with TestThreadContext.
  Thread thread =
      Thread(thread::test::TestOptionsThread0(), notification_acquirer);

  notification_acquirer.WaitUntilRunning();
  // At this point the thread is blocked and waiting on the notification.
  const SystemClock::time_point release_time = SystemClock::now();
  notification_acquirer.Release();
  notification_acquirer.WaitUntilFinished();
  ASSERT_TRUE(notification_acquirer.notified_time().has_value());
  EXPECT_GE(notification_acquirer.notified_time().value(), release_time);

  // Clean up the test thread context.
#if PW_THREAD_JOINING_ENABLED
  thread.join();
#else
  thread.detach();
  thread::test::WaitUntilDetachedThreadsCleanedUp();
#endif  // PW_THREAD_JOINING_ENABLED
}

TEST(TimedThreadNotification, AcquireWithSuspend) {
  TimedNotificationAcquirer notification_acquirer;
  Thread thread =
      Thread(thread::test::TestOptionsThread0(), notification_acquirer);

  notification_acquirer.WaitUntilRunning();

  // Suspend and resume the task before notifying it, which should cause the
  // internal xTaskNotifyWait to stop blocking and return pdFALSE upon resume.
  vTaskSuspend(notification_acquirer.task_handle());
  vTaskResume(notification_acquirer.task_handle());

  // Sleep for at least one tick to ensure the time moved forward to let us
  // observe the unblock time is in fact after resumed it.
  this_thread::sleep_for(SystemClock::duration(1));

  // At this point the thread is blocked and waiting on the notification.
  const SystemClock::time_point release_time = SystemClock::now();
  notification_acquirer.Release();
  notification_acquirer.WaitUntilFinished();
  ASSERT_TRUE(notification_acquirer.notified_time().has_value());
  EXPECT_GE(notification_acquirer.notified_time().value(), release_time);

  // Clean up the test thread context.
#if PW_THREAD_JOINING_ENABLED
  thread.join();
#else
  thread.detach();
  thread::test::WaitUntilDetachedThreadsCleanedUp();
#endif  // PW_THREAD_JOINING_ENABLED
}

#endif  // INCLUDE_vTaskSuspend == 1

}  // namespace pw::sync::freertos
