// 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/cpp/operation.h>

#include <lib/async/cpp/future.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fxl/memory/weak_ptr.h>
#include <lib/gtest/test_loop_fixture.h>

#include "gtest/gtest.h"

namespace modular {
namespace {

class TestContainer : public OperationContainer {
 public:
  TestContainer() : weak_ptr_factory_(this) {}

  fxl::WeakPtr<OperationContainer> GetWeakPtr() override {
    return weak_ptr_factory_.GetWeakPtr();
  }

  int hold_count{0};
  int drop_count{0};
  int cont_count{0};
  OperationBase* last_held = nullptr;
  OperationBase* last_dropped = nullptr;

  void Hold(OperationBase* o) override {
    ++hold_count;
    last_held = o;
  }

  void Drop(OperationBase* o) override {
    ++drop_count;
    last_dropped = o;
  }

  void Cont() override { ++cont_count; }

  void ScheduleTask(fit::pending_task task) override {}

  void PretendToDie() { weak_ptr_factory_.InvalidateWeakPtrs(); }

  using OperationContainer::InvalidateWeakPtrs;  // Promote for testing.
  using OperationContainer::Schedule;            // Promote for testing.

 private:
  fxl::WeakPtrFactory<OperationContainer> weak_ptr_factory_;
};

template <typename... Args>
class TestOperation : public Operation<Args...> {
 public:
  using ResultCall = std::function<void(Args...)>;
  TestOperation(std::function<void()> task, ResultCall done)
      : Operation<Args...>("Test Operation", std::move(done)), task_(task) {}

  void SayDone(Args... args) { this->Done(args...); }

 private:
  void Run() override { task_(); }

  std::function<void()> task_;
};

class OperationTest : public gtest::TestLoopFixture {};

// Test the lifecycle of a single Operation:
// 1) Creating a new operation and adding it to a container
//    causes it to be scheduled (posted to the async task queue).
// 2) When the operation states it is done, the container is told
//    to schedule the next task after the result callback is called.
TEST_F(OperationTest, Lifecycle) {
  TestContainer container;
  bool op_ran = false;
  bool op_done = false;
  auto op =
      std::make_unique<TestOperation<>>([&op_ran] { op_ran = true; },
                                        [&op_done, &container] {
                                          op_done = true;

                                          // When our op is done, we
                                          // expect that the
                                          // OperationContainer that owns
                                          // it has already been told to
                                          // drop it, but we do not expect
                                          // Cont() to have been called.
                                          // That happens after the done
                                          // callback is executed.
                                          EXPECT_EQ(1, container.drop_count);
                                          EXPECT_EQ(0, container.cont_count);
                                        });

  // Add() calls Hold() on our OperationContainer implementation. Hold() is
  // supposed to manage the memory. Ours doesn't.
  // The task doesn't run until OperationContainer::Schedule is called with the
  // operation.
  // TODO(thatguy): TestContainer does not manage memory yet, so passing a
  // naked pointer backed by a unique_ptr<> is safe.
  container.Add(op.get());
  EXPECT_EQ(1, container.hold_count);
  EXPECT_EQ(op.get(), container.last_held);
  EXPECT_EQ(0, container.drop_count);
  EXPECT_EQ(0, container.cont_count);
  EXPECT_FALSE(op_ran);
  EXPECT_FALSE(op_done);

  // Add() does not enqueue the operation to be run, at least not in our
  // implementation of OperationContainer.
  RunLoopUntilIdle();
  EXPECT_FALSE(op_ran);
  EXPECT_FALSE(op_done);
  EXPECT_EQ(1, container.hold_count);
  EXPECT_EQ(0, container.drop_count);
  EXPECT_EQ(0, container.cont_count);

  // OperationContainer impls opt to call Schedule() when they are ready to
  // have an operation enqueued.
  container.Schedule(op.get());

  // So when we advance the async loop, we should see that it started running.
  RunLoopUntilIdle();
  EXPECT_TRUE(op_ran);
  EXPECT_FALSE(op_done);
  EXPECT_EQ(1, container.hold_count);
  EXPECT_EQ(0, container.drop_count);
  EXPECT_EQ(0, container.cont_count);

  // When the operation reports being done, we expect it to be dropped, our
  // done callback run, and the OperationContainer told to continue. These
  // happen in order. The order is verified in our done callback.
  op->SayDone();
  EXPECT_TRUE(op_ran);
  EXPECT_TRUE(op_done);
  EXPECT_EQ(1, container.hold_count);
  EXPECT_EQ(1, container.drop_count);
  EXPECT_EQ(op.get(), container.last_dropped);
  EXPECT_EQ(1, container.cont_count);
}

TEST_F(OperationTest, Lifecycle_ContainerGoesAway) {
  // In this test, we make the Operation think that its container's memory has
  // been cleaned up in its done callback. This manifests itself as the
  // Operation not invoking Cont() on the container.
  TestContainer container;
  bool op_ran = false;
  auto op = std::make_unique<TestOperation<>>(
      [&op_ran]() { op_ran = true; },
      [&container]() { container.PretendToDie(); });

  container.Add(op.get());
  container.Schedule(op.get());
  RunLoopUntilIdle();

  // When the operation reports being done, we expect it to be dropped, our
  // done callback run, and the OperationContainer told to continue. These
  // happen in order. The order is verified in our done callback.
  op->SayDone();
  EXPECT_TRUE(op_ran);
  EXPECT_EQ(1, container.hold_count);
  EXPECT_EQ(1, container.drop_count);
  EXPECT_EQ(op.get(), container.last_dropped);
  EXPECT_EQ(0, container.cont_count);
}

TEST_F(OperationTest, ResultsAreReceived) {
  // Show that when an operation calls Done(), its arguments are
  // passed to the done callback.
  TestContainer container;

  auto op = std::make_unique<TestOperation<int>>(
      [] {}, [](int result) { EXPECT_EQ(42, result); });

  container.Add(op.get());
  container.Schedule(op.get());
  RunLoopUntilIdle();
  op->SayDone(42);
}

class TestFlowTokenOperation : public Operation<int> {
 public:
  TestFlowTokenOperation(ResultCall done)
      : Operation("Test FlowToken Operation", std::move(done)) {}

  // |call_before_flow_dies| is invoked before the FlowToken goes out of scope.
  void SayDone(
      int result, std::function<void()> call_before_flow_dies = [] {}) {
    // When |flow| goes out of scope, it will call Done() for us.
    FlowToken flow{this, &result_};

    // Post the continuation of the operation to an async loop so that we
    // exercise the refcounting of FlowTokens.
    async::PostTask(async_get_default_dispatcher(),
                    [this, flow, result, call_before_flow_dies] {
                      result_ = result;
                      call_before_flow_dies();
                    });
  }

 private:
  void Run() override {}

  int result_;
};

TEST_F(OperationTest, Lifecycle_FlowToken) {
  // FlowTokens simply call Done() for you with whatever results you've pointed
  // it at. NOTE(thatguy): I haven't figured out a good way of testing the
  // refcount goodness of FlowTokens. That said, everything else in the world
  // will crash if they fail.
  TestContainer container;

  bool done_called{false};
  int result{0};
  auto op =
      std::make_unique<TestFlowTokenOperation>([&result, &done_called](int r) {
        done_called = true;
        result = r;
      });

  container.Add(op.get());
  container.Schedule(op.get());
  RunLoopUntilIdle();
  op->SayDone(42);
  // TestFlowTokenOperation posts to the async loop in SayDone(). We shouldn't
  // see Done() called until we run the loop and the FlowToken on the capture
  // list of the callback goes out of scope.
  EXPECT_FALSE(done_called);
  RunLoopUntilIdle();
  EXPECT_EQ(42, result);
}

TEST_F(OperationTest, Lifecycle_FlowToken_OperationGoesAway) {
  // Similar to Lifecycle_FlowToken, but FlowTokens have the behavior that if
  // their "owning" operation dies before they go out of scope (because, ie,
  // some callback is sitting in someone else's memory longer than the
  // operation lives), they don't call Done() on that operation.
  TestContainer container;

  bool done_called = false;
  auto op = std::make_unique<TestFlowTokenOperation>(
      [&done_called](int result) { done_called = true; });

  container.Add(op.get());
  container.Schedule(op.get());
  RunLoopUntilIdle();
  op->SayDone(42,
              [&container, &op]() { container.InvalidateWeakPtrs(op.get()); });
  RunLoopUntilIdle();
  EXPECT_FALSE(done_called);
}

TEST_F(OperationTest, OperationQueue) {
  // Here we test a specific implementation of OperationContainer
  // (OperationQueue), which should only allow one operation to "run" at a
  // given time.
  OperationQueue container;

  // OperationQueue, unlike TestContainer, does own the Operations.
  bool op1_ran = false;
  bool op1_done = false;
  auto* op1 = new TestOperation<>([&op1_ran]() { op1_ran = true; },
                                  [&op1_done]() { op1_done = true; });

  bool op3_ran = false;
  bool op3_done = false;
  auto* op3 = new TestOperation<>([&op3_ran]() { op3_ran = true; },
                                  [&op3_done]() { op3_done = true; });

  // We'll queue |op1|, then a fit::promise ("op2") and another Operation,
  // |op3|.
  container.Add(op1);

  bool op2_ran = false;
  bool op2_done = false;
  fit::suspended_task suspended_op2;
  container.ScheduleTask(
      fit::make_promise([&](fit::context& c) -> fit::result<> {
        if (op2_ran == true) {
          op2_done = true;
          return fit::ok();
        }
        op2_ran = true;
        suspended_op2 = c.suspend_task();
        return fit::pending();
      }));

  container.Add(op3);

  // Nothing has run yet because we haven't run the async loop.
  EXPECT_FALSE(op1_ran);
  EXPECT_FALSE(op1_done);
  EXPECT_FALSE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);
  EXPECT_FALSE(op3_done);

  // Running the loop we expect op1 to have run, but not completed.
  RunLoopUntilIdle();
  EXPECT_TRUE(op1_ran);
  EXPECT_FALSE(op1_done);
  EXPECT_FALSE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);
  EXPECT_FALSE(op3_done);

  // But even if we run more, we do not expect any other ops to run.
  RunLoopUntilIdle();
  EXPECT_TRUE(op1_ran);
  EXPECT_FALSE(op1_done);
  EXPECT_FALSE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);
  EXPECT_FALSE(op3_done);

  // If op1 says it's Done(), we expect op2 to run.
  op1->SayDone();
  RunLoopUntilIdle();
  EXPECT_TRUE(op1_done);
  EXPECT_TRUE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);
  EXPECT_FALSE(op3_done);

  // Running the loop again should do nothing, as op2 is still pending (until
  // we resume it manuall).
  RunLoopUntilIdle();
  EXPECT_TRUE(suspended_op2);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);
  EXPECT_FALSE(op3_done);

  // Resume op2, and run the loop again. We expect op3 to start, but not
  // complete.
  suspended_op2.resume_task();
  RunLoopUntilIdle();
  EXPECT_TRUE(op2_done);
  EXPECT_TRUE(op3_ran);
  EXPECT_FALSE(op3_done);
}

TEST_F(OperationTest, OperationCollection) {
  // OperationCollection starts all operations immediately and lets them run in
  // parallel.
  OperationCollection container;

  // OperationQueue, unlike TestContainer, does manage its memory.
  bool op1_ran = false;
  bool op1_done = false;
  auto* op1 = new TestOperation<>([&op1_ran]() { op1_ran = true; },
                                  [&op1_done]() { op1_done = true; });

  bool op2_ran = false;
  bool op2_done = false;
  auto* op2 = new TestOperation<>([&op2_ran]() { op2_ran = true; },
                                  [&op2_done]() { op2_done = true; });

  container.Add(op1);
  container.Add(op2);
  bool op3_ran = false;
  container.ScheduleTask(fit::make_promise([&] { op3_ran = true; }));

  // Nothing has run yet because we haven't run the async loop.
  EXPECT_FALSE(op1_ran);
  EXPECT_FALSE(op1_done);
  EXPECT_FALSE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_FALSE(op3_ran);

  // Running the loop we expect all ops to have run. TestOperations won't have
  // completed because they require us to call SayDone(). The fit::promise,
  // however, will have completed (it doesn't suspend).
  RunLoopUntilIdle();
  EXPECT_TRUE(op1_ran);
  EXPECT_FALSE(op1_done);
  EXPECT_TRUE(op2_ran);
  EXPECT_FALSE(op2_done);
  EXPECT_TRUE(op2_ran);
}

class TestOperationNotNullPtr : public Operation<> {
 public:
  TestOperationNotNullPtr(const FlowToken& parent_flow_token)
      : Operation("Test Operation on container is not nullptr", [] {}),
        parent_flow_token_(parent_flow_token) {}

 private:
  void Run() override { FlowToken flow{this}; }

  FlowToken parent_flow_token_;
};

class TestQueueNotNullPtr : public Operation<> {
 public:
  TestQueueNotNullPtr(ResultCall done)
      : Operation("TestQueueNotNullPtr", std::move(done)) {}

 private:
  void Run() override {
    // When |flow| goes out of scope, it will call Done() for us.
    FlowToken flow{this};
    operation_queue_.Add(new TestOperationNotNullPtr(flow));
  }

  OperationQueue operation_queue_;
};

class TestCollectionNotNullPtr : public Operation<> {
 public:
  TestCollectionNotNullPtr(ResultCall done)
      : Operation("TestCollectionNotNullPtr", std::move(done)) {}

 private:
  void Run() override {
    // When |flow| goes out of scope, it will call Done() for us.
    FlowToken flow{this};
    operation_collection_.Add(new TestOperationNotNullPtr(flow));
  }

  OperationCollection operation_collection_;
};

// See comments on OperationQueue::Drop.
TEST_F(OperationTest, TestQueueNotNullPtr) {
  OperationQueue container;

  bool done_called{false};
  auto op = new TestQueueNotNullPtr([&done_called] { done_called = true; });

  container.Add(op);

  // Nothing has run yet because we haven't run the async loop.
  EXPECT_FALSE(done_called);

  // Running the loop we expect done_called to be set to true
  RunLoopUntilIdle();
  EXPECT_TRUE(done_called);
}

// See comments on OperationCollection::Drop.
TEST_F(OperationTest, TestCollectionNotNullPtr) {
  OperationQueue container;

  bool done_called{false};
  auto op =
      new TestCollectionNotNullPtr([&done_called] { done_called = true; });

  container.Add(op);

  // Nothing has run yet because we haven't run the async loop.
  EXPECT_FALSE(done_called);

  // Running the loop we expect done_called to be set to true
  RunLoopUntilIdle();
  EXPECT_TRUE(done_called);
}

TEST_F(OperationTest, WrapFutureAsOperation_WithResult) {
  // Show that when we wrap a Future<> as an operation on a queue, it runs.
  bool op_did_start{};
  bool op_did_finish{};

  auto on_run = Future<>::Create(__PRETTY_FUNCTION__);
  auto done = on_run->Map([&]() -> int {
    EXPECT_FALSE(op_did_finish);
    op_did_start = true;
    return 10;
  });

  OperationCollection container;
  container.Add(WrapFutureAsOperation(__PRETTY_FUNCTION__, on_run, done,
                                      std::function<void(int)>([&](int result) {
                                        EXPECT_EQ(10, result);
                                        op_did_finish = true;
                                      })));

  RunLoopUntilIdle();
  EXPECT_TRUE(op_did_start);
  EXPECT_TRUE(op_did_finish);
}

TEST_F(OperationTest, WrapFutureAsOperation_WithoutResult) {
  // Show that when we wrap a Future<> as an operation on a queue, it runs.
  bool op_did_start{};
  bool op_did_finish{};

  auto on_run = Future<>::Create(__PRETTY_FUNCTION__);
  auto done = on_run->Then([&] {
    EXPECT_FALSE(op_did_finish);
    op_did_start = true;
  });

  OperationCollection container;
  container.Add(WrapFutureAsOperation(
      __PRETTY_FUNCTION__, on_run, done,
      std::function<void()>([&] { op_did_finish = true; })));

  RunLoopUntilIdle();
  EXPECT_TRUE(op_did_start);
  EXPECT_TRUE(op_did_finish);
}

}  // namespace
}  // namespace modular
