// Copyright 2018 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 <lib/async-testing/test_loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/time.h>
#include <lib/async/cpp/wait.h>
#include <lib/async/default.h>
#include <lib/async/dispatcher.h>
#include <lib/async/task.h>
#include <lib/fit/function.h>
#include <lib/zx/event.h>
#include <lib/zx/time.h>
#include <sys/socket.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <array>
#include <memory>
#include <utility>

#include <zxtest/zxtest.h>

namespace {

// Initializes |wait| to wait on |event| to call |closure| once |trigger| is
// signaled.
void InitWait(async::Wait* wait, fit::closure closure, const zx::event& event,
              zx_signals_t trigger) {
  wait->set_handler([closure = std::move(closure)](async_dispatcher_t*, async::Wait*, zx_status_t,
                                                   const zx_packet_signal_t*) { closure(); });
  wait->set_object(event.get());
  wait->set_trigger(trigger);
}

TEST(TestLoopTest, DefaultDispatcherIsSetAndUnset) {
  ASSERT_NULL(async_get_default_dispatcher());
  {
    async::TestLoop loop;
    EXPECT_EQ(loop.dispatcher(), async_get_default_dispatcher());
  }
  EXPECT_NULL(async_get_default_dispatcher());
}

TEST(TestLoopDispatcher, FakeClockTimeIsCorrect) {
  async::TestLoop loop;

  EXPECT_EQ(0, loop.Now().get());
  EXPECT_EQ(0, async::Now(loop.dispatcher()).get());

  loop.RunUntilIdle();
  EXPECT_EQ(0, loop.Now().get());
  EXPECT_EQ(0, async::Now(loop.dispatcher()).get());

  loop.RunFor(zx::nsec(1));
  EXPECT_EQ(1, loop.Now().get());
  EXPECT_EQ(1, async::Now(loop.dispatcher()).get());

  loop.RunUntil(zx::time() + zx::nsec(3));
  EXPECT_EQ(3, loop.Now().get());
  EXPECT_EQ(3, async::Now(loop.dispatcher()).get());

  loop.RunFor(zx::nsec(7));
  EXPECT_EQ(10, loop.Now().get());
  EXPECT_EQ(10, async::Now(loop.dispatcher()).get());

  loop.RunUntil(zx::time() + zx::nsec(12));
  EXPECT_EQ(12, loop.Now().get());
  EXPECT_EQ(12, async::Now(loop.dispatcher()).get());

  // t = 12, so nothing should happen in trying to reset the clock to t = 10.
  loop.RunUntil(zx::time() + zx::nsec(10));
  EXPECT_EQ(12, loop.Now().get());
  EXPECT_EQ(12, async::Now(loop.dispatcher()).get());
}

TEST(TestLoopTest, TasksAreDispatched) {
  async::TestLoop loop;
  bool called = false;
  async::PostDelayedTask(
      loop.dispatcher(), [&called] { called = true; }, zx::sec(2));

  // t = 1: nothing should happen.
  loop.RunFor(zx::sec(1));
  EXPECT_FALSE(called);

  // t = 2: task should be dispatched.
  loop.RunFor(zx::sec(1));
  EXPECT_TRUE(called);

  called = false;
  async::PostTask(loop.dispatcher(), [&called] { called = true; });
  loop.RunUntilIdle();
  EXPECT_TRUE(called);
}

TEST(TestLoopTest, SameDeadlinesDispatchInPostingOrder) {
  async::TestLoop loop;
  bool calledA = false;
  bool calledB = false;

  async::PostTask(loop.dispatcher(), [&] {
    EXPECT_FALSE(calledB);
    calledA = true;
  });
  async::PostTask(loop.dispatcher(), [&] {
    EXPECT_TRUE(calledA);
    calledB = true;
  });

  loop.RunUntilIdle();
  EXPECT_TRUE(calledA);
  EXPECT_TRUE(calledB);

  calledA = false;
  calledB = false;
  async::PostDelayedTask(
      loop.dispatcher(),
      [&] {
        EXPECT_FALSE(calledB);
        calledA = true;
      },
      zx::sec(5));
  async::PostDelayedTask(
      loop.dispatcher(),
      [&] {
        EXPECT_TRUE(calledA);
        calledB = true;
      },
      zx::sec(5));

  loop.RunFor(zx::sec(5));
  EXPECT_TRUE(calledA);
  EXPECT_TRUE(calledB);
}

// Test tasks that post tasks.
TEST(TestLoopTest, NestedTasksAreDispatched) {
  async::TestLoop loop;
  bool called = false;

  async::PostTask(loop.dispatcher(), [&] {
    async::PostDelayedTask(
        loop.dispatcher(),
        [&] {
          async::PostDelayedTask(
              loop.dispatcher(), [&] { called = true; }, zx::min(25));
        },
        zx::min(35));
  });

  loop.RunFor(zx::hour(1));
  EXPECT_TRUE(called);
}

TEST(TestLoopTest, TimeIsCorrectWhileDispatching) {
  async::TestLoop loop;
  bool called = false;

  async::PostTask(loop.dispatcher(), [&] {
    EXPECT_EQ(0, loop.Now().get());

    async::PostDelayedTask(
        loop.dispatcher(),
        [&] {
          EXPECT_EQ(10, loop.Now().get());
          async::PostDelayedTask(
              loop.dispatcher(),
              [&] {
                EXPECT_EQ(15, loop.Now().get());
                async::PostTask(loop.dispatcher(), [&] {
                  EXPECT_EQ(15, loop.Now().get());
                  called = true;
                });
              },
              zx::nsec(5));
        },
        zx::nsec(10));
  });

  loop.RunFor(zx::nsec(15));
  EXPECT_TRUE(called);
}

TEST(TestLoopTest, TasksAreCanceled) {
  async::TestLoop loop;
  bool calledA = false;
  bool calledB = false;
  bool calledC = false;

  async::TaskClosure taskA([&calledA] { calledA = true; });
  async::TaskClosure taskB([&calledB] { calledB = true; });
  async::TaskClosure taskC([&calledC] { calledC = true; });

  ASSERT_OK(taskA.Post(loop.dispatcher()));
  ASSERT_OK(taskB.Post(loop.dispatcher()));
  ASSERT_OK(taskC.Post(loop.dispatcher()));

  ASSERT_OK(taskA.Cancel());
  ASSERT_OK(taskC.Cancel());

  loop.RunUntilIdle();

  EXPECT_FALSE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);
}

TEST(TestLoopTest, TimeIsAdvanced) {
  async::TestLoop loop;

  bool called = false;
  async::TaskClosure task([&called] { called = true; });
  auto time1 = async::Now(loop.dispatcher());

  ASSERT_EQ(ZX_OK, task.PostDelayed(loop.dispatcher(), zx::duration(1)));

  loop.RunUntilIdle();

  EXPECT_FALSE(called);
  EXPECT_EQ(time1.get(), async::Now(loop.dispatcher()).get());

  loop.AdvanceTimeByEpsilon();

  auto time2 = async::Now(loop.dispatcher());

  EXPECT_FALSE(called);
  EXPECT_GT(time2.get(), time1.get());

  loop.RunUntilIdle();

  EXPECT_TRUE(called);
  EXPECT_EQ(time2.get(), async::Now(loop.dispatcher()).get());
}

TEST(TestLoopTest, WaitsAreDispatched) {
  async::TestLoop loop;
  async::Wait wait;
  zx::event event;
  bool called = false;

  ASSERT_EQ(ZX_OK, zx::event::create(0u, &event));
  InitWait(
      &wait, [&called] { called = true; }, event, ZX_USER_SIGNAL_0);
  ASSERT_EQ(ZX_OK, wait.Begin(loop.dispatcher()));

  // |wait| has not yet been triggered.
  loop.RunUntilIdle();
  EXPECT_FALSE(called);

  ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_1));

  // |wait| will only be triggered by |ZX_USER_SIGNAL_0|.
  loop.RunUntilIdle();
  EXPECT_FALSE(called);

  ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_0));

  loop.RunUntilIdle();
  EXPECT_TRUE(called);
}

// Test waits that trigger waits.
TEST(TestLoopTest, NestedWaitsAreDispatched) {
  async::TestLoop loop;
  zx::event event;
  async::Wait waitA;
  async::Wait waitB;
  async::Wait waitC;
  bool calledA = false;
  bool calledB = false;
  bool calledC = false;

  ASSERT_EQ(ZX_OK, zx::event::create(0u, &event));
  InitWait(
      &waitA,
      [&] {
        InitWait(
            &waitB,
            [&] {
              InitWait(
                  &waitC, [&] { calledC = true; }, event, ZX_USER_SIGNAL_2);
              waitC.Begin(loop.dispatcher());
              calledB = true;
            },
            event, ZX_USER_SIGNAL_1);
        waitB.Begin(loop.dispatcher());
        calledA = true;
      },
      event, ZX_USER_SIGNAL_0);

  ASSERT_EQ(ZX_OK, waitA.Begin(loop.dispatcher()));

  loop.RunUntilIdle();
  EXPECT_FALSE(calledA);
  EXPECT_FALSE(calledB);
  EXPECT_FALSE(calledC);

  ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_0));

  loop.RunUntilIdle();
  EXPECT_TRUE(calledA);
  EXPECT_FALSE(calledB);
  EXPECT_FALSE(calledC);

  ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_1));

  loop.RunUntilIdle();
  EXPECT_TRUE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);

  ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_2));

  loop.RunUntilIdle();
  EXPECT_TRUE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_TRUE(calledC);
}

TEST(TestLoopTest, WaitsAreCanceled) {
  async::TestLoop loop;
  zx::event event;
  async::Wait waitA;
  async::Wait waitB;
  async::Wait waitC;
  bool calledA = false;
  bool calledB = false;
  bool calledC = false;

  ASSERT_EQ(ZX_OK, zx::event::create(0u, &event));

  InitWait(
      &waitA, [&calledA] { calledA = true; }, event, ZX_USER_SIGNAL_0);
  InitWait(
      &waitB, [&calledB] { calledB = true; }, event, ZX_USER_SIGNAL_0);
  InitWait(
      &waitC, [&calledC] { calledC = true; }, event, ZX_USER_SIGNAL_0);

  ASSERT_OK(waitA.Begin(loop.dispatcher()));
  ASSERT_OK(waitB.Begin(loop.dispatcher()));
  ASSERT_OK(waitC.Begin(loop.dispatcher()));

  ASSERT_OK(waitA.Cancel());
  ASSERT_OK(waitC.Cancel());
  ASSERT_OK(event.signal(0u, ZX_USER_SIGNAL_0));

  loop.RunUntilIdle();
  EXPECT_FALSE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);
}

// Test a task that begins a wait to post a task.
TEST(TestLoopTest, NestedTasksAndWaitsAreDispatched) {
  async::TestLoop loop;
  zx::event event;
  async::Wait wait;
  bool wait_begun = false;
  bool wait_dispatched = false;
  bool inner_task_dispatched = false;

  ASSERT_OK(zx::event::create(0u, &event));
  InitWait(
      &wait,
      [&] {
        async::PostDelayedTask(
            loop.dispatcher(), [&] { inner_task_dispatched = true; }, zx::min(2));
        wait_dispatched = true;
      },
      event, ZX_USER_SIGNAL_0);
  async::PostDelayedTask(
      loop.dispatcher(),
      [&] {
        wait.Begin(loop.dispatcher());
        wait_begun = true;
      },
      zx::min(3));

  loop.RunFor(zx::min(3));
  EXPECT_TRUE(wait_begun);
  EXPECT_FALSE(wait_dispatched);
  EXPECT_FALSE(inner_task_dispatched);

  ASSERT_OK(event.signal(0u, ZX_USER_SIGNAL_0));

  loop.RunUntilIdle();
  EXPECT_TRUE(wait_begun);
  EXPECT_TRUE(wait_dispatched);
  EXPECT_FALSE(inner_task_dispatched);

  loop.RunFor(zx::min(2));
  EXPECT_TRUE(wait_begun);
  EXPECT_TRUE(wait_dispatched);
  EXPECT_TRUE(inner_task_dispatched);
}

TEST(TestLoopTest, DefaultDispatcherIsCurrentLoop) {
  async::TestLoop loop;
  auto subloop = loop.StartNewLoop();
  bool main_loop_task_run = false;
  async_dispatcher_t* main_loop_task_dispatcher = nullptr;
  bool sub_loop_task_run = false;
  async_dispatcher_t* sub_loop_task_dispatcher = nullptr;

  async::PostTask(loop.dispatcher(), [&] {
    main_loop_task_run = true;
    main_loop_task_dispatcher = async_get_default_dispatcher();
  });

  async::PostTask(subloop->dispatcher(), [&] {
    sub_loop_task_run = true;
    sub_loop_task_dispatcher = async_get_default_dispatcher();
  });

  loop.RunUntilIdle();
  EXPECT_TRUE(main_loop_task_run);
  EXPECT_EQ(main_loop_task_dispatcher, loop.dispatcher());
  EXPECT_TRUE(sub_loop_task_run);
  EXPECT_EQ(sub_loop_task_dispatcher, subloop->dispatcher());
}

TEST(TestLoopTest, HugeAmountOfTaskAreDispatched) {
  constexpr size_t kPostCount = 128 * 1024;
  async::TestLoop loop;
  zx::event event;
  ASSERT_OK(zx::event::create(0u, &event));

  size_t called_count = 0;
  size_t wait_count = 0;
  // Creating the array on the heap as its size is greater than the available
  // stack.
  auto waits_ptr = std::make_unique<std::array<async::Wait, kPostCount>>();
  auto& waits = *waits_ptr;

  for (size_t i = 0; i < kPostCount; ++i) {
    InitWait(
        &waits[i], [&] { wait_count++; }, event, ZX_USER_SIGNAL_0);
    ASSERT_OK(waits[i].Begin(loop.dispatcher()));
  }
  ASSERT_OK(event.signal(0u, ZX_USER_SIGNAL_0));
  for (size_t i = 0; i < kPostCount; ++i) {
    async::PostTask(loop.dispatcher(), [&] { called_count++; });
  }

  loop.RunUntilIdle();

  EXPECT_EQ(kPostCount, called_count);
  EXPECT_EQ(kPostCount, wait_count);
}

TEST(TestLoopTest, TasksAreDispatchedOnManyLoops) {
  async::TestLoop loop;
  auto loopA = loop.StartNewLoop();
  auto loopB = loop.StartNewLoop();
  auto loopC = loop.StartNewLoop();

  bool called = false;
  bool calledA = false;
  bool calledB = false;
  bool calledC = false;
  async::TaskClosure taskC([&calledC] { calledC = true; });

  async::PostTask(loopB->dispatcher(), [&calledB] { calledB = true; });
  async::PostDelayedTask(
      loop.dispatcher(), [&called] { called = true; }, zx::sec(1));
  ASSERT_OK(taskC.PostDelayed(loopC->dispatcher(), zx::sec(1)));
  async::PostDelayedTask(
      loopA->dispatcher(), [&calledA] { calledA = true; }, zx::sec(2));

  loop.RunUntilIdle();
  EXPECT_FALSE(called);
  EXPECT_FALSE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);

  taskC.Cancel();
  loop.RunFor(zx::sec(1));
  EXPECT_TRUE(called);
  EXPECT_FALSE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);

  loop.RunFor(zx::sec(1));
  EXPECT_TRUE(called);
  EXPECT_TRUE(calledA);
  EXPECT_TRUE(calledB);
  EXPECT_FALSE(calledC);
}

TEST(TestLoopTest, WaitsAreDispatchedOnManyLoops) {
  async::TestLoop loop;
  auto loopA = loop.StartNewLoop();
  auto loopB = loop.StartNewLoop();
  auto loopC = loop.StartNewLoop();
  async::Wait wait;
  async::Wait waitA;
  async::Wait waitB;
  async::Wait waitC;
  bool called = false;
  bool calledA = false;
  bool calledB = false;
  bool calledC = false;
  zx::event event;

  ASSERT_EQ(ZX_OK, zx::event::create(0u, &event));

  InitWait(
      &wait, [&called] { called = true; }, event, ZX_USER_SIGNAL_0);
  InitWait(
      &waitA, [&calledA] { calledA = true; }, event, ZX_USER_SIGNAL_0);
  InitWait(
      &waitB, [&calledB] { calledB = true; }, event, ZX_USER_SIGNAL_0);
  InitWait(
      &waitC, [&calledC] { calledC = true; }, event, ZX_USER_SIGNAL_0);

  ASSERT_OK(wait.Begin(loop.dispatcher()));
  ASSERT_OK(waitA.Begin(loopA->dispatcher()));
  ASSERT_OK(waitB.Begin(loopB->dispatcher()));
  ASSERT_OK(waitC.Begin(loopC->dispatcher()));

  ASSERT_OK(waitB.Cancel());
  ASSERT_OK(event.signal(0u, ZX_USER_SIGNAL_0));

  loop.RunUntilIdle();
  EXPECT_TRUE(called);
  EXPECT_TRUE(calledA);
  EXPECT_FALSE(calledB);
  EXPECT_TRUE(calledC);
}

// Populates |order| with the order in which two tasks and two waits on four
// loops were dispatched, given a |loop|.
void DetermineDispatchOrder(std::unique_ptr<async::TestLoop> loop, int (*order)[4]) {
  auto loopA = loop->StartNewLoop();
  auto loopB = loop->StartNewLoop();
  auto loopC = loop->StartNewLoop();
  async::Wait wait;
  async::Wait waitB;
  zx::event event;
  int i = 0;

  ASSERT_OK(zx::event::create(0u, &event));

  InitWait(
      &wait, [&] { (*order)[0] = ++i; }, event, ZX_USER_SIGNAL_0);
  async::PostTask(loopA->dispatcher(), [&] { (*order)[1] = ++i; });
  InitWait(
      &waitB, [&] { (*order)[2] = ++i; }, event, ZX_USER_SIGNAL_0);
  async::PostTask(loopC->dispatcher(), [&] { (*order)[3] = ++i; });

  ASSERT_OK(wait.Begin(loop->dispatcher()));
  ASSERT_OK(waitB.Begin(loopB->dispatcher()));
  ASSERT_OK(event.signal(0u, ZX_USER_SIGNAL_0));

  loop->RunUntilIdle();

  EXPECT_EQ(4, i);
  EXPECT_NE(0, (*order)[0]);
  EXPECT_NE(0, (*order)[1]);
  EXPECT_NE(0, (*order)[2]);
  EXPECT_NE(0, (*order)[3]);
}

void SeedTestLoopWithEnv(uint32_t random_seed, std::unique_ptr<async::TestLoop>* loop) {
  char buf[12];
  snprintf(buf, sizeof(buf), "%u", random_seed);
  EXPECT_EQ(0, setenv("TEST_LOOP_RANDOM_SEED", buf, 1));
  *loop = std::make_unique<async::TestLoop>();
  EXPECT_EQ(0, unsetenv("TEST_LOOP_RANDOM_SEED"));
}

void DispatchOrderIsDeterministicFor(uint32_t random_seed) {
  int expected_order[4] = {0, 0, 0, 0};
  std::unique_ptr<async::TestLoop> loop;

  ASSERT_NO_FAILURES(SeedTestLoopWithEnv(random_seed, &loop));
  ASSERT_NO_FAILURES(DetermineDispatchOrder(std::move(loop), &expected_order));

  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 2; j++) {
      int actual_order[4] = {0, 0, 0, 0};
      if (j == 0) {
        ASSERT_NO_FAILURES(SeedTestLoopWithEnv(random_seed, &loop));
      } else {
        loop = std::make_unique<async::TestLoop>(random_seed);
      }
      ASSERT_NO_FAILURES(DetermineDispatchOrder(std::move(loop), &actual_order));
      EXPECT_EQ(expected_order[0], actual_order[0]);
      EXPECT_EQ(expected_order[1], actual_order[1]);
      EXPECT_EQ(expected_order[2], actual_order[2]);
      EXPECT_EQ(expected_order[3], actual_order[3]);
    }
  }
}

TEST(TestLoopTest, DispatchOrderIsDeterministic) {
  DispatchOrderIsDeterministicFor(1);
  DispatchOrderIsDeterministicFor(43);
  DispatchOrderIsDeterministicFor(893);
  DispatchOrderIsDeterministicFor(39408);
  DispatchOrderIsDeterministicFor(844018);
  DispatchOrderIsDeterministicFor(83018299);
  DispatchOrderIsDeterministicFor(3213);
  DispatchOrderIsDeterministicFor(139133113);
  DispatchOrderIsDeterministicFor(1323234373);
}

void BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(uint32_t random_seed) {
  std::unique_ptr<async::TestLoop> loop;

  ASSERT_NO_FAILURES(SeedTestLoopWithEnv(random_seed, &loop));
  auto loopB = loop->StartNewLoop();
  std::vector<int> elements;

  async::PostTask(loop->dispatcher(), [&] {
    async::PostTask(loopB->dispatcher(), [&] { elements.push_back(0); });
    EXPECT_TRUE(loop->BlockCurrentSubLoopAndRunOthersUntil(
        [&] { return elements.size() == 1 && elements[0] == 0; }));
    elements.push_back(1);
  });

  loop->RunUntilIdle();
  EXPECT_EQ(elements.size(), 2);
  EXPECT_EQ(elements[0], 0);
  EXPECT_EQ(elements[1], 1);
}

TEST(TestLoopTest, BlockCurrentSubLoopAndRunOthersUntilOtherLoop) {
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(1);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(43);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(893);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(39408);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(844018);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(83018299);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(3213);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(139133113);
  BlockCurrentSubLoopAndRunOthersUntilOtherLoopFor(1323234373);
}

void BlocksFinishWhenOtherLoopQuitFor(uint32_t random_seed) {
  std::unique_ptr<async::TestLoop> loop;

  ASSERT_NO_FAILURES(SeedTestLoopWithEnv(random_seed, &loop));
  auto loopB = loop->StartNewLoop();
  auto loopC = loop->StartNewLoop();

  async::PostTask(loop->dispatcher(), [&] { loop->Quit(); });
  bool loopB_called = false;
  async::PostTask(loopB->dispatcher(), [&] { loopB_called = true; });
  bool block_current_subloop = false;
  async::PostTask(loopC->dispatcher(), [&] {
    block_current_subloop =
        loop->BlockCurrentSubLoopAndRunOthersUntil([&] { return loopB_called; });
  });

  auto time = loop->Now();
  loop->RunFor(zx::sec(1));
  // Run until Idle for the case where the Quit() task is scheduled before the
  // blocking task. This ensure that all task have been run, but doesn't advance
  // the time.
  loop->RunUntilIdle();

  EXPECT_TRUE(loopB_called);
  EXPECT_TRUE(block_current_subloop);
  // Time should not have flown, as a Quit() has been posted.
  EXPECT_EQ(time.get(), loop->Now().get());
}

TEST(TestLoopTest, BlocksFinishWhenOtherLoopQuit) {
  BlocksFinishWhenOtherLoopQuitFor(1);
  BlocksFinishWhenOtherLoopQuitFor(43);
  BlocksFinishWhenOtherLoopQuitFor(893);
  BlocksFinishWhenOtherLoopQuitFor(39408);
  BlocksFinishWhenOtherLoopQuitFor(844018);
  BlocksFinishWhenOtherLoopQuitFor(83018299);
  BlocksFinishWhenOtherLoopQuitFor(3213);
  BlocksFinishWhenOtherLoopQuitFor(139133113);
  BlocksFinishWhenOtherLoopQuitFor(1323234373);
}

void BlocksWhileOtherLoopAdvanceTimeFor(uint32_t random_seed) {
  std::unique_ptr<async::TestLoop> loop;

  ASSERT_NO_FAILURES(SeedTestLoopWithEnv(random_seed, &loop));
  auto loopB = loop->StartNewLoop();

  auto initial_time = loop->Now();
  bool block_current_subloop = false;

  async::PostTask(loop->dispatcher(), [&] { loop->AdvanceTimeByEpsilon(); });
  async::PostTask(loopB->dispatcher(), [&] {
    block_current_subloop =
        loop->BlockCurrentSubLoopAndRunOthersUntil([&] { return loop->Now() > initial_time; });
  });
  loop->RunUntilIdle();

  EXPECT_TRUE(block_current_subloop);
  EXPECT_TRUE(loop->Now() > initial_time);
}

TEST(TestLoopTest, BlocksWhileOtherLoopAdvanceTime) {
  BlocksWhileOtherLoopAdvanceTimeFor(1);
  BlocksWhileOtherLoopAdvanceTimeFor(43);
  BlocksWhileOtherLoopAdvanceTimeFor(893);
  BlocksWhileOtherLoopAdvanceTimeFor(39408);
  BlocksWhileOtherLoopAdvanceTimeFor(844018);
  BlocksWhileOtherLoopAdvanceTimeFor(83018299);
  BlocksWhileOtherLoopAdvanceTimeFor(3213);
  BlocksWhileOtherLoopAdvanceTimeFor(139133113);
  BlocksWhileOtherLoopAdvanceTimeFor(1323234373);
}

// Test that non-async-dispatcher loops run fine.
struct ExternalLoop : async_test_subloop_t {
  ExternalLoop() { ops = &kOps; }

  // The loop keeps a state, that is repeatedly incremented.
  // 0: advance to 1
  // 1: wait until |time_ >= kState1Deadline|, advance to 2
  // 2: advance to 3
  // 3: blocked, needs to be manually advanced
  // 4: advance to 5
  // 5: done, do not increment
  // 6: finalized
  int state_ = 0;

  // The current time, according to the TestLoop.
  zx_time_t time_ = ZX_TIME_INFINITE_PAST;

  constexpr static zx_time_t kState1Deadline = 1000;
  constexpr static int kStateFinalized = 6;

  // Returns the minimum time for the next transition starting from |state|.
  // If |ZX_TIME_INFINITE| is returned, the state should not be advanced.
  static zx_time_t NextTransitionTime(int state) {
    switch (state) {
      case 0:
      case 2:
      case 4:
        // Advance immediately.
        return ZX_TIME_INFINITE_PAST;
      case 1:
        return kState1Deadline;
      case 3:
      case 5:
        return ZX_TIME_INFINITE;
      default:
        ZX_ASSERT(false);
    }
  }

  static void advance_time_to(async_test_subloop_t* self_generic, zx_time_t time) {
    ExternalLoop* self = static_cast<ExternalLoop*>(self_generic);
    ZX_ASSERT(self->state_ != kStateFinalized);
    static_cast<ExternalLoop*>(self)->time_ = time;
  }

  static uint8_t dispatch_next_due_message(async_test_subloop_t* self_generic) {
    ExternalLoop* self = static_cast<ExternalLoop*>(self_generic);
    ZX_ASSERT(self->state_ != kStateFinalized);
    zx_time_t transition_time = NextTransitionTime(self->state_);
    if (transition_time != ZX_TIME_INFINITE && transition_time <= self->time_) {
      self->state_++;
      return true;
    } else {
      return false;
    }
  }

  static uint8_t has_pending_work(async_test_subloop_t* self_generic) {
    ExternalLoop* self = static_cast<ExternalLoop*>(self_generic);
    ZX_ASSERT(self->state_ != kStateFinalized);
    zx_time_t transition_time = NextTransitionTime(self->state_);
    return (transition_time != ZX_TIME_INFINITE && transition_time <= self->time_);
  }

  static zx_time_t get_next_task_due_time(async_test_subloop_t* self_generic) {
    ExternalLoop* self = static_cast<ExternalLoop*>(self_generic);
    ZX_ASSERT(self->state_ != kStateFinalized);
    return NextTransitionTime(self->state_);
  }

  static void finalize(async_test_subloop_t* self_generic) {
    ExternalLoop* self = static_cast<ExternalLoop*>(self_generic);
    ZX_ASSERT(self->state_ != kStateFinalized);
    self->state_ = kStateFinalized;
  }

  constexpr static async_test_subloop_ops_t kOps = {advance_time_to, dispatch_next_due_message,
                                                    has_pending_work, get_next_task_due_time,
                                                    finalize};
};

TEST(TestLoopTest, ExternalLoopIsRunAndFinalized) {
  auto loop = std::make_unique<async::TestLoop>();
  ExternalLoop subloop;
  auto token = loop->RegisterLoop(&subloop);
  EXPECT_TRUE(loop->RunUntilIdle());
  EXPECT_EQ(1, subloop.state_);

  EXPECT_TRUE(loop->RunUntil(zx::time(subloop.kState1Deadline)));
  EXPECT_EQ(3, subloop.state_);
  EXPECT_LE(subloop.kState1Deadline, subloop.time_);

  subloop.state_ = 4;
  EXPECT_TRUE(loop->RunUntilIdle());
  EXPECT_EQ(5, subloop.state_);

  token.reset();
  EXPECT_EQ(subloop.kStateFinalized, subloop.state_);
}

TEST(TestLoopTest, BlockCurrentSubLoopAndRunOthersUntilTrue) {
  async::TestLoop loop;
  bool block_current_subloop = false;
  async::PostTask(loop.dispatcher(), [&] {
    block_current_subloop = loop.BlockCurrentSubLoopAndRunOthersUntil([] { return true; });
  });

  loop.RunUntilIdle();
  EXPECT_TRUE(block_current_subloop);
}

TEST(TestLoopTest, BlockCurrentSubLoopAndRunOthersUntilFalse) {
  async::TestLoop loop;
  bool block_current_subloop = true;
  async::PostTask(loop.dispatcher(), [&] {
    block_current_subloop = loop.BlockCurrentSubLoopAndRunOthersUntil([] { return false; });
  });

  loop.RunUntilIdle();
  EXPECT_FALSE(block_current_subloop);
}

struct Task {
  async_task_t task;
  bool handled = false;
};

void ReentrantHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t result) {
  // This is reentrant.
  auto* typed_task = reinterpret_cast<Task*>(task);
  typed_task->handled = true;
  async::Now(dispatcher);
}

// This test just verifies that reentrant tasks dont hang and that proper lock releases exists.
TEST(TestLoopTest, TaskHandlerIsReentrant) {
  async::TestLoop loop;

  auto task_factory = [] {
    Task task;
    task.task.state = ASYNC_STATE_INIT;
    task.task.handler = &ReentrantHandler;
    return task;
  };

  auto dispatched_task = task_factory();
  // Dispatching it
  EXPECT_OK(async_post_task(loop.dispatcher(), &dispatched_task.task));
  loop.RunUntilIdle();
  EXPECT_TRUE(dispatched_task.handled);

  // Cancelling it.
  auto cancelled_task = task_factory();
  EXPECT_OK(async_post_task(loop.dispatcher(), &cancelled_task.task));
  EXPECT_OK(async_cancel_task(loop.dispatcher(), &cancelled_task.task));

  // On Shutdown
  auto shutdown_task = task_factory();
  {
    async::TestLoop shutdown_loop;
    EXPECT_OK(async_post_task(shutdown_loop.dispatcher(), &shutdown_task.task));
  }
  EXPECT_TRUE(shutdown_task.handled);
}

void ReentrantWaitHandler(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_status_t status,
                          const zx_packet_signal_t* signal) {
  async::Now(dispatcher);
}

TEST(TestLoopTest, WaitHandlerIsReentrant) {
  async::TestLoop loop;
  zx::event event;
  ASSERT_OK(zx::event::create(0, &event));

  auto wait_factory = [&event] {
    async_wait_t wait;
    wait.state = ASYNC_STATE_INIT;
    wait.handler = &ReentrantWaitHandler;
    wait.object = event.borrow()->get();
    wait.trigger = ZX_USER_SIGNAL_0;
    wait.options = 0;
    return wait;
  };

  auto dispatched_wait = wait_factory();
  // Dispatching activated wait.
  ASSERT_OK(async_begin_wait(loop.dispatcher(), &dispatched_wait));
  event.signal(0, ZX_USER_SIGNAL_0);
  loop.RunUntilIdle();

  // Cancelling it.
  auto cancelled_wait = wait_factory();
  ASSERT_OK(async_begin_wait(loop.dispatcher(), &cancelled_wait));
  ASSERT_OK(async_cancel_wait(loop.dispatcher(), &cancelled_wait));
  loop.RunUntilIdle();

  // On Shutdown
  auto shutdown_wait = wait_factory();
  {
    async::TestLoop shutdown_loop;

    ASSERT_OK(async_begin_wait(shutdown_loop.dispatcher(), &shutdown_wait));
  }
}

}  // namespace
