// 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 "gtest/gtest.h"
#include "pw_async/test_dispatcher.h"
#include "pw_sync/thread_notification.h"
#include "pw_thread/thread.h"
#include "pw_thread_stl/options.h"

using namespace std::chrono_literals;

namespace pw::async {

// Lambdas can only capture one ptr worth of memory without allocating, so we
// group the data we want to share between tasks and their containing tests
// inside one struct.
struct TestPrimitives {
  int count = 0;
  sync::ThreadNotification notification;
};

TEST(TestDispatcher, PostTasks) {
  TestDispatcher dispatcher;

  TestPrimitives tp;
  auto inc_count = [&tp]([[maybe_unused]] Context& c) { ++tp.count; };

  Task task(inc_count);
  dispatcher.PostTask(task);

  Task task2(inc_count);
  dispatcher.PostTask(task2);

  Task task3([&tp]([[maybe_unused]] Context& c) { ++tp.count; });
  dispatcher.PostTask(task3);

  dispatcher.RunUntilIdle();
  dispatcher.RequestStop();

  ASSERT_TRUE(tp.count == 3);
}

struct TaskPair {
  Task task_a;
  Task task_b;
  int count = 0;
  sync::ThreadNotification notification;
};

TEST(TestDispatcher, DelayedTasks) {
  TestDispatcher dispatcher;
  TaskPair tp;

  Task task0(
      [&tp]([[maybe_unused]] Context& c) { tp.count = tp.count * 10 + 4; });

  dispatcher.PostDelayedTask(task0, 200ms);

  Task task1([&tp]([[maybe_unused]] Context& c) {
    tp.count = tp.count * 10 + 1;
    c.dispatcher->PostDelayedTask(tp.task_a, 50ms);
    c.dispatcher->PostDelayedTask(tp.task_b, 25ms);
  });

  dispatcher.PostDelayedTask(task1, 100ms);

  tp.task_a.SetFunction(
      [&tp]([[maybe_unused]] Context& c) { tp.count = tp.count * 10 + 3; });

  tp.task_b.SetFunction(
      [&tp]([[maybe_unused]] Context& c) { tp.count = tp.count * 10 + 2; });

  dispatcher.RunUntilIdle();
  dispatcher.RequestStop();

  ASSERT_TRUE(tp.count == 1234);
}

TEST(TestDispatcher, CancelTasks) {
  TestDispatcher dispatcher;

  TestPrimitives tp;
  auto inc_count = [&tp]([[maybe_unused]] Context& c) { ++tp.count; };

  // This task gets canceled in the last task.
  Task task0(inc_count);
  dispatcher.PostDelayedTask(task0, 40ms);

  // This task gets canceled immediately.
  Task task1(inc_count);
  dispatcher.PostDelayedTask(task1, 10ms);
  ASSERT_TRUE(dispatcher.Cancel(task1));

  // This task cancels the first task.
  Task cancel_task(
      [&task0](Context& c) { ASSERT_TRUE(c.dispatcher->Cancel(task0)); });
  dispatcher.PostDelayedTask(cancel_task, 20ms);

  dispatcher.RunUntilIdle();
  dispatcher.RequestStop();

  ASSERT_TRUE(tp.count == 0);
}

// Test RequestStop() from inside task.
TEST(TestDispatcher, RequestStopInsideTask) {
  TestDispatcher dispatcher;

  TestPrimitives tp;
  auto inc_count = [&tp]([[maybe_unused]] Context& c) { ++tp.count; };

  // These tasks are never executed and cleaned up in RequestStop().
  Task task0(inc_count), task1(inc_count);
  dispatcher.PostDelayedTask(task0, 20ms);
  dispatcher.PostDelayedTask(task1, 21ms);

  Task stop_task([&tp]([[maybe_unused]] Context& c) {
    ++tp.count;
    c.dispatcher->RequestStop();
  });
  dispatcher.PostTask(stop_task);

  dispatcher.RunUntilIdle();

  ASSERT_TRUE(tp.count == 1);
}

TEST(TestDispatcher, PeriodicTasks) {
  TestDispatcher dispatcher;

  TestPrimitives tp;

  Task periodic_task([&tp]([[maybe_unused]] Context& c) { ++tp.count; });
  dispatcher.SchedulePeriodicTask(periodic_task, 20ms, dispatcher.Now() + 50ms);

  // Cancel periodic task after it has run thrice, at +50ms, +70ms, and +90ms.
  Task cancel_task(
      [&periodic_task](Context& c) { c.dispatcher->Cancel(periodic_task); });
  dispatcher.PostDelayedTask(cancel_task, 100ms);

  dispatcher.RunUntilIdle();
  dispatcher.RequestStop();

  ASSERT_TRUE(tp.count == 3);
}

}  // namespace pw::async
