// 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 <zxtest/zxtest.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(dispatcher.now.get(), dispatcher.last_task->deadline);
    EXPECT_EQ(dispatcher.now.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(dispatcher.now.get(), dispatcher.last_task->deadline);
    EXPECT_EQ(dispatcher.now.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>();
}
