// 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 <lib/async-testing/dispatcher_stub.h>
#include <lib/async/cpp/task.h>

#include <gtest/gtest.h>

namespace {

class MockDispatcher : public async::DispatcherStub {
 public:
  enum class Op {
    NONE,
    POST_TASK,
    CANCEL_TASK,
  };

  zx::time Now() override { return now; }

  zx_status_t PostTask(async_task_t* task) override {
    last_op = Op::POST_TASK;
    last_task = task;
    return next_status;
  }

  zx_status_t CancelTask(async_task_t* task) override {
    last_op = Op::CANCEL_TASK;
    last_task = task;
    return next_status;
  }

  zx::time now{42};
  Op last_op = Op::NONE;
  async_task_t* last_task = nullptr;
  zx_status_t next_status = ZX_OK;
};

class Harness {
 public:
  Harness() { Reset(); }

  void Reset() {
    handler_ran = false;
    last_task = nullptr;
    last_status = ZX_ERR_INTERNAL;
  }

  void Handler(async_dispatcher_t* dispatcher, async::TaskBase* task, zx_status_t status) {
    handler_ran = true;
    last_task = task;
    last_status = status;
  }

  void ClosureHandler() {
    handler_ran = true;
    last_task = &task();
    last_status = ZX_OK;
  }

  virtual async::TaskBase& task() = 0;
  virtual bool dispatches_failures() = 0;

  bool handler_ran;
  async::TaskBase* last_task;
  zx_status_t last_status;
};

class LambdaHarness : public Harness {
 public:
  async::TaskBase& task() override { return task_; }
  bool dispatches_failures() override { return true; }

 private:
  async::Task task_{[this](async_dispatcher_t* dispatcher, async::Task* task, zx_status_t status) {
    Handler(dispatcher, task, status);
  }};
};

class MethodHarness : public Harness {
 public:
  async::TaskBase& task() override { return task_; }
  bool dispatches_failures() override { return true; }

 private:
  async::TaskMethod<Harness, &Harness::Handler> task_{this};
};

class ClosureLambdaHarness : public Harness {
 public:
  async::TaskBase& task() override { return task_; }
  bool dispatches_failures() override { return false; }

 private:
  async::TaskClosure task_{[this] { ClosureHandler(); }};
};

class ClosureMethodHarness : public Harness {
 public:
  async::TaskBase& task() override { return task_; }
  bool dispatches_failures() override { return false; }

 private:
  async::TaskClosureMethod<Harness, &Harness::ClosureHandler> task_{this};
};

TEST(TaskTests, task_set_handler_test) {
  {
    async::Task task;
    EXPECT_FALSE(task.has_handler());
    EXPECT_FALSE(task.is_pending());
    EXPECT_EQ(zx::time::infinite().get(), task.last_deadline().get());

    task.set_handler([](async_dispatcher_t* dispatcher, async::Task* task, zx_status_t status) {});
    EXPECT_TRUE(task.has_handler());
  }

  {
    async::Task task([](async_dispatcher_t* dispatcher, async::Task* task, zx_status_t status) {});
    EXPECT_TRUE(task.has_handler());
    EXPECT_FALSE(task.is_pending());
    EXPECT_EQ(zx::time::infinite().get(), task.last_deadline().get());
  }
}

TEST(TaskTests, task_closure_set_handler_test) {
  {
    async::TaskClosure task;
    EXPECT_FALSE(task.has_handler());
    EXPECT_FALSE(task.is_pending());
    EXPECT_EQ(zx::time::infinite().get(), task.last_deadline().get());

    task.set_handler([] {});
    EXPECT_TRUE(task.has_handler());
  }

  {
    async::TaskClosure task([] {});
    EXPECT_TRUE(task.has_handler());
    EXPECT_FALSE(task.is_pending());
    EXPECT_EQ(zx::time::infinite().get(), task.last_deadline().get());
  }
}

template <typename Harness>
void task_post_test() {
  MockDispatcher dispatcher;

  {
    Harness harness;
    dispatcher.next_status = ZX_OK;
    EXPECT_EQ(ZX_OK, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(zx::time::infinite_past().get(), dispatcher.last_task->deadline);
    EXPECT_EQ(zx::time::infinite_past().get(), harness.task().last_deadline().get());
    EXPECT_TRUE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);

    harness.Reset();
    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_ALREADY_EXISTS, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::CANCEL_TASK, dispatcher.last_op);

  {
    Harness harness;
    dispatcher.next_status = ZX_ERR_BAD_STATE;
    EXPECT_EQ(ZX_ERR_BAD_STATE, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(zx::time::infinite_past().get(), dispatcher.last_task->deadline);
    EXPECT_EQ(zx::time::infinite_past().get(), harness.task().last_deadline().get());
    EXPECT_FALSE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
}

template <typename Harness>
void task_post_delayed_test() {
  MockDispatcher dispatcher;

  {
    Harness harness;
    dispatcher.next_status = ZX_OK;
    EXPECT_EQ(ZX_OK, harness.task().PostDelayed(&dispatcher, zx::nsec(5)));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(dispatcher.now.get() + 5, dispatcher.last_task->deadline);
    EXPECT_EQ(dispatcher.now.get() + 5, harness.task().last_deadline().get());
    EXPECT_TRUE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);

    harness.Reset();
    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_ALREADY_EXISTS, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::CANCEL_TASK, dispatcher.last_op);

  {
    Harness harness;
    dispatcher.next_status = ZX_ERR_BAD_STATE;
    EXPECT_EQ(ZX_ERR_BAD_STATE, harness.task().PostDelayed(&dispatcher, zx::nsec(6)));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(dispatcher.now.get() + 6, dispatcher.last_task->deadline);
    EXPECT_EQ(dispatcher.now.get() + 6, harness.task().last_deadline().get());
    EXPECT_FALSE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
}

template <typename Harness>
void task_post_for_time_test() {
  MockDispatcher dispatcher;

  {
    Harness harness;
    dispatcher.next_status = ZX_OK;
    EXPECT_EQ(ZX_OK, harness.task().PostForTime(&dispatcher, zx::time(55)));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(55, dispatcher.last_task->deadline);
    EXPECT_EQ(55, harness.task().last_deadline().get());
    EXPECT_TRUE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);

    harness.Reset();
    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_ALREADY_EXISTS, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::CANCEL_TASK, dispatcher.last_op);

  {
    Harness harness;
    dispatcher.next_status = ZX_ERR_BAD_STATE;
    EXPECT_EQ(ZX_ERR_BAD_STATE, harness.task().PostForTime(&dispatcher, zx::time(56)));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_EQ(56, dispatcher.last_task->deadline);
    EXPECT_EQ(56, harness.task().last_deadline().get());
    EXPECT_FALSE(harness.task().is_pending());
    EXPECT_FALSE(harness.handler_ran);
  }
  EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
}

template <typename Harness>
void task_cancel_test() {
  MockDispatcher dispatcher;

  {
    Harness harness;
    EXPECT_FALSE(harness.task().is_pending());

    EXPECT_EQ(ZX_ERR_NOT_FOUND, harness.task().Cancel());
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.task().is_pending());

    EXPECT_EQ(ZX_OK, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_TRUE(harness.task().is_pending());

    EXPECT_EQ(ZX_OK, harness.task().Cancel());
    EXPECT_EQ(MockDispatcher::Op::CANCEL_TASK, dispatcher.last_op);
    EXPECT_FALSE(harness.task().is_pending());

    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_NOT_FOUND, harness.task().Cancel());
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.task().is_pending());
  }
  EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
}

template <typename Harness>
void task_run_handler_test() {
  MockDispatcher dispatcher;

  // success status
  {
    Harness harness;
    EXPECT_FALSE(harness.task().is_pending());

    EXPECT_EQ(ZX_OK, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_TRUE(harness.task().is_pending());

    harness.Reset();
    dispatcher.last_task->handler(&dispatcher, dispatcher.last_task, ZX_OK);
    EXPECT_TRUE(harness.handler_ran);
    EXPECT_EQ(&harness.task(), harness.last_task);
    EXPECT_EQ(ZX_OK, harness.last_status);
    EXPECT_FALSE(harness.task().is_pending());

    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_NOT_FOUND, harness.task().Cancel());
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.task().is_pending());
  }
  EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);

  // failure status
  {
    Harness harness;
    EXPECT_FALSE(harness.task().is_pending());

    EXPECT_EQ(ZX_OK, harness.task().Post(&dispatcher));
    EXPECT_EQ(MockDispatcher::Op::POST_TASK, dispatcher.last_op);
    EXPECT_TRUE(harness.task().is_pending());

    harness.Reset();
    dispatcher.last_task->handler(&dispatcher, dispatcher.last_task, ZX_ERR_CANCELED);
    EXPECT_FALSE(harness.task().is_pending());
    if (harness.dispatches_failures()) {
      EXPECT_TRUE(harness.handler_ran);
      EXPECT_EQ(&harness.task(), harness.last_task);
      EXPECT_EQ(ZX_ERR_CANCELED, harness.last_status);
    } else {
      EXPECT_FALSE(harness.handler_ran);
    }

    dispatcher.last_op = MockDispatcher::Op::NONE;
    EXPECT_EQ(ZX_ERR_NOT_FOUND, harness.task().Cancel());
    EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
    EXPECT_FALSE(harness.task().is_pending());
  }
  EXPECT_EQ(MockDispatcher::Op::NONE, dispatcher.last_op);
}

TEST(TaskTests, unsupported_post_task_test) {
  async::DispatcherStub dispatcher;
  async_task_t task{};
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, async_post_task(&dispatcher, &task)) << "valid args";
}

TEST(TaskTests, unsupported_cancel_task_test) {
  async::DispatcherStub dispatcher;
  async_task_t task{};
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, async_cancel_task(&dispatcher, &task)) << "valid args";
}

}  // namespace

TEST(TaskTests, task_post_test_LambdaHarness) { task_post_test<LambdaHarness>(); }

TEST(TaskTests, task_post_test_MethodHarness) { task_post_test<MethodHarness>(); }

TEST(TaskTests, task_post_test_ClosureLambdaHarness) { task_post_test<ClosureLambdaHarness>(); }

TEST(TaskTests, task_post_test_ClosureMethodHarness) { task_post_test<ClosureMethodHarness>(); }

TEST(TaskTests, task_post_delayed_test_LambdaHarness) { task_post_delayed_test<LambdaHarness>(); }

TEST(TaskTests, task_post_delayed_test_MethodHarness) { task_post_delayed_test<MethodHarness>(); }

TEST(TaskTests, task_post_delayed_test_ClosureLambdaHarness) {
  task_post_delayed_test<ClosureLambdaHarness>();
}

TEST(TaskTests, task_post_delayed_test_ClosureMethodHarness) {
  task_post_delayed_test<ClosureMethodHarness>();
}

TEST(TaskTests, task_post_for_time_test_LambdaHarness) { task_post_for_time_test<LambdaHarness>(); }

TEST(TaskTests, task_post_for_time_test_MethodHarness) { task_post_for_time_test<MethodHarness>(); }

TEST(TaskTests, task_post_for_time_test_ClosureLambdaHarness) {
  task_post_for_time_test<ClosureLambdaHarness>();
}

TEST(TaskTests, task_post_for_time_test_ClosureMethodHarness) {
  task_post_for_time_test<ClosureMethodHarness>();
}

TEST(TaskTests, task_cancel_test_LambdaHarness) { task_cancel_test<LambdaHarness>(); }

TEST(TaskTests, task_cancel_test_MethodHarness) { task_cancel_test<MethodHarness>(); }

TEST(TaskTests, task_cancel_test_ClosureLambdaHarness) { task_cancel_test<ClosureLambdaHarness>(); }

TEST(TaskTests, task_cancel_test_ClosureMethodHarness) { task_cancel_test<ClosureMethodHarness>(); }

TEST(TaskTests, task_run_handler_test_LambdaHarness) { task_run_handler_test<LambdaHarness>(); }

TEST(TaskTests, task_run_handler_test_MethodHarness) { task_run_handler_test<MethodHarness>(); }

TEST(TaskTests, task_run_handler_test_ClosureLambdaHarness) {
  task_run_handler_test<ClosureLambdaHarness>();
}

TEST(TaskTests, task_run_handler_test_ClosureMethodHarness) {
  task_run_handler_test<ClosureMethodHarness>();
}
