// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/callback/scoped_task_runner.h"

#include <lib/async-testing/test_loop.h>
#include <pthread.h>

#include <thread>

#include <gtest/gtest.h>

#include "src/lib/fxl/macros.h"

namespace callback {
namespace {

constexpr zx::duration kInterval = zx::min(4);  // to save the world

struct MoveOnly {
  MoveOnly(bool b) : called(b) {}
  MoveOnly(MoveOnly&&) = default;
  bool called;
  FXL_DISALLOW_COPY_AND_ASSIGN(MoveOnly);
};

TEST(ScopedTaskRunnerTest, RunsTaskInScope) {
  bool called = false;
  ScopedTaskRunner tasks;
  tasks.MakeScoped([&] { called = true; })();
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunnerTest, TaskWithArg) {
  bool called = false;
  ScopedTaskRunner tasks;
  tasks.MakeScoped([&](bool value) { called = value; })(true);
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunnerTest, TaskWithRefArg) {
  bool called = false;
  ScopedTaskRunner tasks;
  tasks.MakeScoped([](bool& called) { called = true; })(called);
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunnerTest, TaskWithMoveOnlyArg) {
  bool called = false;
  ScopedTaskRunner tasks;
  tasks.MakeScoped([&](MoveOnly arg) { called = arg.called; })({true});
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunnerTest, TaskWithMoveOnlyCapture) {
  bool called = false;
  ScopedTaskRunner tasks;
  MoveOnly move_only{true};
  tasks.MakeScoped([&called, move_only = std::move(move_only)] { called = move_only.called; })();
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunnerTest, CancelsTaskOutOfScope) {
  bool called = false;
  fit::closure task;
  {
    ScopedTaskRunner tasks;
    task = tasks.MakeScoped([&] { called = true; });
  }
  task();
  EXPECT_FALSE(called);
}

TEST(ScopedTaskRunnerTest, ExplicitShutdown) {
  bool called = false;
  ScopedTaskRunner tasks;
  auto task = tasks.MakeScoped([&] { called = true; });
  tasks.ShutDown();
  task();
  EXPECT_FALSE(called);
}

TEST(ScopedTaskRunnerTest, MakeScopedAfterShutdown) {
  bool called = false;
  ScopedTaskRunner tasks;
  tasks.ShutDown();
  tasks.MakeScoped([&] { called = true; })();
  EXPECT_FALSE(called);
}

TEST(ScopedTaskRunnerTest, Reset) {
  bool beforeCalled = false, afterCalled = false;
  ScopedTaskRunner tasks;
  auto before = tasks.MakeScoped([&] { beforeCalled = true; });
  tasks.Reset();
  auto after = tasks.MakeScoped([&] { afterCalled = true; });
  before();
  after();
  EXPECT_FALSE(beforeCalled);
  EXPECT_TRUE(afterCalled);
}

TEST(ScopedTaskRunnerTest, DestroyDuringTaskOnThread) {
  bool called = false;
  auto* tasks = new ScopedTaskRunner;
  tasks->MakeScoped([&] {
    delete tasks;
    called = true;
  })();
  EXPECT_TRUE(called);
}

TEST(ScopedTaskRunner, PostTaskAndFriends) {
  async::TestLoop loop;

  uint8_t called = 0;
  auto increment_call = [&called] { ++called; };
  ScopedTaskRunner task_runner(loop.dispatcher());
  task_runner.PostTask(increment_call);
  task_runner.PostDelayedTask(increment_call, zx::sec(0));
  task_runner.PostTaskForTime(increment_call, zx::time(0));

  loop.RunUntilIdle();
  EXPECT_EQ(3u, called);
}

TEST(ScopedTaskRunner, PostTaskAndFriendsCancelOnDeletion) {
  async::TestLoop loop;

  uint8_t called = 0;
  auto increment_call = [&called] { ++called; };

  {
    ScopedTaskRunner task_runner(loop.dispatcher());
    task_runner.PostTask(increment_call);
    task_runner.PostDelayedTask(increment_call, zx::sec(0));
    task_runner.PostTaskForTime(increment_call, zx::time(0));
  }

  loop.RunUntilIdle();
  EXPECT_EQ(0u, called);
}

TEST(ScopedTaskRunnerTest, PostPeriodicTask) {
  async::TestLoop loop;
  int called = 0;
  {
    ScopedTaskRunner tasks(loop.dispatcher());
    tasks.PostPeriodicTask([&] { called++; }, kInterval, false);
    loop.RunFor(kInterval * 4);
  }

  EXPECT_EQ(4, called);

  called = 0;
  loop.RunFor(kInterval * 4);
  EXPECT_EQ(0, called);
}

// Verifies that all occurrences of a periodic task posted from a non-dispatch
// thread execute on the dispatch thread.
//
// Example bug:
// https://fuchsia.googlesource.com/garnet/+/3a8dab9a939efeeb5e18454595a558f9972f7a42/public/lib/callback/scoped_task_runner.cc#47
TEST(ScopedTaskRunnerTest, PostPeriodicTaskOffThread) {
  async::TestLoop loop;
  ScopedTaskRunner tasks(loop.dispatcher());

  pthread_t dispatch_thread = pthread_self();

  int called = 0;
  std::thread foreign_thread([&] {
    // test-correctness assertion
    EXPECT_NE(dispatch_thread, pthread_self());

    tasks.PostPeriodicTask(
        [&] {
          ++called;
          EXPECT_EQ(dispatch_thread, pthread_self()) << "iteration " << called;
        },
        kInterval, true);
  });
  foreign_thread.join();

  loop.RunFor(kInterval * 4);

  EXPECT_EQ(5, called);
}

}  // namespace
}  // namespace callback
