// Copyright 2020 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/modular/lib/async/cpp/future.h"

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

#include <memory>
#include <string>

#include <gtest/gtest.h>

#include "gtest/gtest-spi.h"

namespace modular {

namespace {

// https://www.reddit.com/r/Stargate/comments/114165/stargate_sg_1_episode_200_what_is_your_favorite/c6j8ryy
// https://en.wikiquote.org/wiki/Stargate_SG-1/Season_10#200_[10.6]
// (The actual duration is immaterial because we control time in unit tests.)
constexpr zx::duration kPause = zx::min(38);

// This is a simple class to enable asynchronous callbacks to be tested. In each
// test:
//
// 1. Instantiate an AsyncExceptions object,
// 2. Call Signal() in each async callback to indicate that an async callback
//    was successfully called. Note that doesn't mean that the callback itself
//    was passed the correct parameters or was successful: to ensure that, your
//    callback should call still EXPECT_* for its expected results.
// 3. Call Verify(n) at the end of your test method to ensure that the number of
//    expected async callbacks is correct. |n| should be the number of Signal()
//    calls that were expected. Verify() will fail if Signal() hasn't been
//    called exactly |n| times.
//
// Note that AsyncExpectations does _not_ integrate with the message loop, since
// its one use case has no need to do that.
//
// THIS CLASS IS NOT THREAD-SAFE.
//
// Example:
//
// TEST(FooTest, FooTestCase) {
//   AsyncExpectations async_expectations;
//   async_function_1([&] {
//     async_expectations.Signal();
//   });
//   async_function_2([&] {
//     async_expectations.Signal();
//   });
//   async_expectations.Verify(2);
// }
class AsyncExpectations {
 public:
  void Signal() { ++count_; }
  void Reset() { count_ = 0; }

  int count() const { return count_; }

 private:
  int count_ = 0;
};

TEST(AsyncExpectationTest, TestLessThanExpectedCountFails) {
  AsyncExpectations async_expectations;

  async_expectations.Signal();
  EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(2, async_expectations.count()); }, "Expected equality");
}

TEST(AsyncExpectationTest, TestExpectedCountSucceeds) {
  AsyncExpectations async_expectations;

  async_expectations.Signal();
  EXPECT_EQ(1, async_expectations.count());
}

TEST(AsyncExpectationTest, TestMoreThanExpectedCountFails) {
  AsyncExpectations async_expectations;

  async_expectations.Signal();
  async_expectations.Signal();
  EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(1, async_expectations.count()); }, "Expected equality");
}

}  // namespace

// FutureTest must be in the ::modular namespace (not in an anonymous namespace)
// so that the "friend class FutureTest;" declaration in the Future class can
// properly befriend this test.
class FutureTest : public ::testing::Test {
 protected:
  template <typename... Result>
  const std::tuple<Result...>& get(const FuturePtr<Result...>& future) const {
    return future->get();
  }

  template <typename... Result>
  fxl::WeakPtrFactory<Future<Result...>>& weak_factory(const FuturePtr<Result...>& future) const {
    return future->weak_factory_;
  }
};

namespace {

TEST_F(FutureTest, Create) {
  auto f = Future<>::Create(__PRETTY_FUNCTION__);

  EXPECT_NE(f.get(), nullptr);
}

TEST_F(FutureTest, CompleteAndGet) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  f->Complete(10);
  ASSERT_EQ(get(f), std::tuple<int>(10));
}

TEST_F(FutureTest, ThenWith0Argument) {
  auto f = Future<>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Then([&]() { async_expectations.Signal(); });

  f->Complete();
  ASSERT_EQ(get(f), std::tuple<>());

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, ThenWith1Argument) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Then([&](const int& value) {
    EXPECT_EQ(value, 10);
    async_expectations.Signal();
  });

  f->Complete(10);

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, ThenWith2Argument) {
  auto f = Future<int, float>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Then([&](const int& i, const float& f) {
    EXPECT_EQ(i, 10);
    EXPECT_FLOAT_EQ(f, 3.14f);
    async_expectations.Signal();
  });

  f->Complete(10, 3.14f);

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, CompleteBeforeThen) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  f->Complete(10);

  AsyncExpectations async_expectations;

  f->Then([&](const int& value) {
    EXPECT_EQ(value, 10);
    async_expectations.Signal();
  });

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, ThenCorrectlyMoves) {
  std::shared_ptr<int> p(new int(10));
  auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Then([&](std::shared_ptr<int> p2) {
    EXPECT_EQ(p.get(), nullptr);
    EXPECT_NE(p2.get(), nullptr);

    EXPECT_EQ(*p2, 10);
    async_expectations.Signal();
  });

  f->Complete(std::move(p));

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, ConstThen) {
  std::shared_ptr<int> p(new int(10));
  auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->ConstThen([&](const std::shared_ptr<int>& p2) {
    EXPECT_NE(p2.get(), nullptr);
    EXPECT_EQ(p.get(), nullptr);

    EXPECT_EQ(*p2, 10);
    async_expectations.Signal();
  });

  f->ConstThen([&](const std::shared_ptr<int>& p3) {
    EXPECT_NE(p3.get(), nullptr);
    EXPECT_EQ(p.get(), nullptr);

    EXPECT_EQ(*p3, 10);
    async_expectations.Signal();
  });

  f->Complete(std::move(p));

  EXPECT_EQ(2, async_expectations.count());
}

TEST_F(FutureTest, ConstThenAfterComplete) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  bool first_const_then{};
  f->ConstThen([&](const int& i) {
    EXPECT_FALSE(first_const_then);
    first_const_then = true;
    async_expectations.Signal();
  });

  f->Complete(10);

  bool second_const_then{};
  f->ConstThen([&](const int& i) {
    EXPECT_FALSE(second_const_then);
    second_const_then = true;
    async_expectations.Signal();
  });

  EXPECT_EQ(2, async_expectations.count());
}

TEST_F(FutureTest, ConstThenAfterThen) {
  std::shared_ptr<int> p(new int(10));
  auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->ConstThen([&](const std::shared_ptr<int>& p2) {
    EXPECT_NE(p2.get(), nullptr);
    EXPECT_EQ(p.get(), nullptr);

    EXPECT_EQ(*p2, 10);
    async_expectations.Signal();
  });

  f->Then([&](std::shared_ptr<int> p4) {
    EXPECT_NE(p4.get(), nullptr);
    EXPECT_EQ(p.get(), nullptr);

    EXPECT_EQ(*p4, 10);
    async_expectations.Signal();
  });

  f->ConstThen([&](const std::shared_ptr<int>& p3) {
    EXPECT_NE(p3.get(), nullptr);
    EXPECT_EQ(p.get(), nullptr);

    EXPECT_EQ(*p3, 10);
    async_expectations.Signal();
  });

  f->Complete(std::move(p));

  EXPECT_EQ(3, async_expectations.count());
}

TEST_F(FutureTest, WeakThen) {
  // WeakThen() will break an execution chain if its weakptr is invalidated.
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);
  AsyncExpectations async_expectations;

  // This time we expect all three to run because we haven't invalidated any
  // WeakPtrs.
  auto f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
  f->Then([&] { async_expectations.Signal(); })
      ->WeakThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); })
      ->Then([&] { async_expectations.Signal(); });

  f->Complete();
  EXPECT_EQ(3, async_expectations.count());

  // But this time we'll invalidate WeakPtrs in the first Then(). Only the first
  // Then() will run.
  async_expectations.Reset();
  f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  f->Then([&] {
     async_expectations.Signal();
     factory.InvalidateWeakPtrs();
   })
      ->WeakThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); })
      ->Then([&] { async_expectations.Signal(); });

  f->Complete();
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WeakConstThen) {
  // WeakConstThen() will not run if its weakptr is invalidated.
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);
  AsyncExpectations async_expectations;

  auto f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
  f->WeakConstThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); });
  f->Complete();
  EXPECT_EQ(1, async_expectations.count());

  async_expectations.Reset();
  f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  f->WeakConstThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); });
  factory.InvalidateWeakPtrs();
  f->Complete();
  EXPECT_EQ(0, async_expectations.count());
}

TEST_F(FutureTest, WeakMap) {
  // Similar to WeakThen(), but using Map calls instead.
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);

  auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  // First let everything run.
  AsyncExpectations async_expectations;
  f->Map([&](int i) {
     async_expectations.Signal();
     return 42;
   })
      ->WeakMap(factory.GetWeakPtr(),
                [&](int i) {
                  async_expectations.Signal();
                  return 10;
                })
      ->Then([&](int i) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(3, async_expectations.count());

  // Now invalidate it.
  f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  async_expectations.Reset();
  f->Map([&](int i) {
     async_expectations.Signal();
     factory.InvalidateWeakPtrs();
     return 42;
   })
      ->WeakMap(factory.GetWeakPtr(),
                [&](int i) {
                  async_expectations.Signal();
                  return 10;
                })
      ->Then([&](int i) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WeakAsyncMap) {
  // Similar to WeakThen(), but using Map calls instead.
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);

  auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  // First let everything run.
  AsyncExpectations async_expectations;
  f->Map([&](int i) {
     async_expectations.Signal();
     return 42;
   })
      ->WeakAsyncMap(factory.GetWeakPtr(),
                     [&](int i) {
                       async_expectations.Signal();
                       return Future<int>::CreateCompleted(
                           std::string(__PRETTY_FUNCTION__) + std::string("2"), 10);
                     })
      ->Then([&](int i) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(3, async_expectations.count());

  // Now invalidate it.
  f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("3"));
  async_expectations.Reset();
  f->Map([&](int i) {
     async_expectations.Signal();
     factory.InvalidateWeakPtrs();
     return 42;
   })
      ->WeakAsyncMap(factory.GetWeakPtr(),
                     [&](int i) {
                       async_expectations.Signal();
                       return Future<int>::CreateCompleted(
                           std::string(__PRETTY_FUNCTION__) + std::string("4"), 10);
                     })
      ->Then([&](int i) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, CreateCompleted) {
  auto f = Future<>::CreateCompleted(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Then([&]() { async_expectations.Signal(); });

  ASSERT_EQ(get(f), std::tuple<>());

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, Wait) {
  auto f1 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
  auto f2 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  auto f3 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("3"));

  AsyncExpectations async_expectations;

  auto f = Wait(std::string(__PRETTY_FUNCTION__) + std::string("4"), {f1, f2, f3});
  f->Then([&](std::vector<std::tuple<int, std::string>> v) {
    EXPECT_EQ(v.size(), 3ul);

    EXPECT_EQ(v[0], std::make_tuple(10, "10"));
    EXPECT_EQ(v[1], std::make_tuple(20, "20"));
    EXPECT_EQ(v[2], std::make_tuple(30, "30"));

    async_expectations.Signal();
  });

  // Go ahead and insert out of order to also ensure that Wait produces results
  // in insertion order rather than completion order.
  f2->Complete(20, "20");
  EXPECT_EQ(0, async_expectations.count());
  f1->Complete(10, "10");
  EXPECT_EQ(0, async_expectations.count());
  f3->Complete(30, "30");

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitOnZeroFutures) {
  auto f = Wait(__PRETTY_FUNCTION__, std::vector<FuturePtr<int>>{});

  AsyncExpectations async_expectations;

  f->Then([&](std::vector<int> v) {
    EXPECT_EQ(v.size(), 0ul);
    async_expectations.Signal();
  });

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitReleasesReturnedFutureIfAllComponentFuturesHaveBeenCompletedOrDestroyed) {
  fxl::WeakPtr<Future<std::vector<int>>> weak_f;

  auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
  {
    auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
    weak_f = weak_factory(Wait(__PRETTY_FUNCTION__ + std::string("Wait"), {f1, f2})).GetWeakPtr();
  }

  ASSERT_TRUE(weak_f);
  weak_f->Then([&](std::vector<int>) { FAIL(); });
  f1->Complete(42);
  EXPECT_FALSE(weak_f);
}

// This test is the happy case, more or less identical to |Wait|.
TEST_F(FutureTest, WaitWithTimeout) {
  auto f1 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
  auto f2 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  auto f3 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("3"));

  AsyncExpectations async_expectations;
  async::TestLoop loop;

  auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("4"), loop.dispatcher(),
                           kPause, [](const std::string& msg) { FAIL() << msg; }, {f1, f2, f3});

  f->Then([&](std::vector<std::tuple<int, std::string>> v) {
    EXPECT_EQ(v.size(), 3ul);

    EXPECT_EQ(v[0], std::make_tuple(10, "10"));
    EXPECT_EQ(v[1], std::make_tuple(20, "20"));
    EXPECT_EQ(v[2], std::make_tuple(30, "30"));

    async_expectations.Signal();
  });

  loop.RunUntilIdle();  // ensure the timeout does not occur

  // Go ahead and insert out of order to also ensure that Wait produces results
  // in insertion order rather than completion order.
  f2->Complete(20, "20");
  EXPECT_EQ(0, async_expectations.count());
  f1->Complete(10, "10");
  EXPECT_EQ(0, async_expectations.count());
  f3->Complete(30, "30");

  EXPECT_EQ(1, async_expectations.count());
}

// Zero futures should instantly complete regardless of timeout.
TEST_F(FutureTest, WaitWithTimeoutOnZeroFutures) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  auto f = WaitWithTimeout(
      __PRETTY_FUNCTION__, loop.dispatcher(), {}, [](const std::string& msg) { FAIL() << msg; },
      std::vector<FuturePtr<int>>{});

  loop.RunUntilIdle();

  f->Then([&](std::vector<int> v) {
    EXPECT_EQ(v.size(), 0ul);
    async_expectations.Signal();
  });

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitWithTimeoutCallsCallbackOnTimeout) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  auto f1 = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  auto f =
      WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"), loop.dispatcher(), {},
                      [&](const std::string& msg) {
                        EXPECT_EQ('1', msg[msg.size() - 1]);
                        async_expectations.Signal();
                      },
                      {f1});

  loop.RunUntilIdle();
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitWithTimeoutWithDefaultDispatcher) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  async_set_default_dispatcher(loop.dispatcher());

  auto f1 = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"), {},
                           [&](const std::string& msg) {
                             EXPECT_EQ('1', msg[msg.size() - 1]);
                             async_expectations.Signal();
                           },
                           {f1});

  loop.RunUntilIdle();
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitWithTimeoutDoesNotCompleteAfterTimeout) {
  async::TestLoop loop;

  auto f1 = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"), loop.dispatcher(),
                           {}, [](const auto&) {}, {f1});

  f->Then([] { FAIL(); });

  loop.RunUntilIdle();
  f1->Complete();
}

// The following several tests also test additional Wait functionality, since
// WaitWithTimeout is implemented in terms of Wait.
TEST_F(FutureTest, WaitWithTimeoutOnMoveOnlyType) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  auto f1 =
      Future<std::unique_ptr<int>>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"), loop.dispatcher(),
                           kPause, [](const std::string& msg) { FAIL() << msg; }, {f1});

  f->Then([&](std::vector<std::unique_ptr<int>> v) {
    EXPECT_EQ(v.size(), 1u);

    EXPECT_EQ(*v[0], 42);

    async_expectations.Signal();
  });

  f1->Complete(std::make_unique<int>(42));
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitWithTimeoutNoTypeStreamlining) {
  // This test contains no assertions as it is a compile-time test.
  async::TestLoop loop;
  auto f1 = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  auto f = WaitWithTimeout<Future<std::vector<std::tuple<>>>>(
      std::string(__PRETTY_FUNCTION__) + std::string("2"), loop.dispatcher(), kPause,
      [](const auto&) {}, {f1});
  f->Then([](std::vector<std::tuple<>> v) {});
}

// This tests a specific bug case where some futures started completed and some
// did not. In this bug, WaitWithTimeout added its notification const callbacks
// after invoking Wait. The futures that were completed would invoke the
// callback added by Wait immediately, making the const callbacks then added by
// WaitWithTimeout illegal. This did not manifest when all futures started
// completed due to an optimization in WaitWithTimeout that returns immediately
// if the Wait future starts complete.
TEST_F(FutureTest, WaitWithTimeoutOnPartiallyCompletedFutures) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
  auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
  f1->Complete(42);
  auto f = WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"), loop.dispatcher(), kPause,
                           [](const auto&) {}, {f1, f2})
               ->Then([&](const std::vector<int>& results) {
                 ASSERT_EQ(2u, results.size());
                 EXPECT_EQ(42, results[0]);
                 EXPECT_EQ(54, results[1]);
                 async_expectations.Signal();
               });
  f2->Complete(54);  // http://hitchhikers.wikia.com/wiki/42
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WaitWithTimeoutReleasesFuturesOnCompletion) {
  async::TestLoop loop;
  fxl::WeakPtr<Future<>> weak_f1;

  {
    auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
    weak_f1 = weak_factory(f1).GetWeakPtr();

    auto f = WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"), loop.dispatcher(), kPause,
                             [](const auto&) {}, {f1});
    f1->Complete();
  }

  EXPECT_FALSE(weak_f1);
}

TEST_F(FutureTest, WaitWithTimeoutReleasesFuturesOnTimeout) {
  async::TestLoop loop;
  fxl::WeakPtr<Future<>> weak_f1;

  {
    auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
    weak_f1 = weak_factory(f1).GetWeakPtr();

    WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"), loop.dispatcher(), {},
                    [](const auto&) {}, {f1});
    loop.RunUntilIdle();
  }

  EXPECT_FALSE(weak_f1);
}

TEST_F(FutureTest, WaitWithTimeoutCallsCallbackOnTimeoutEvenIfFuturesAreDestroyed) {
  AsyncExpectations async_expectations;
  async::TestLoop loop;

  {
    auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
    WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"), loop.dispatcher(), {},
                    [&](const auto&) { async_expectations.Signal(); }, {f1});
  }

  loop.RunUntilIdle();
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest,
       WaitWithTimeoutReleasesReturnedFutureIfAllComponentFuturesHaveBeenCompletedOrDestroyed) {
  async::TestLoop loop;
  fxl::WeakPtr<Future<std::vector<int>>> weak_f;

  auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
  {
    auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
    weak_f = weak_factory(WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
                                          loop.dispatcher(), kPause, [](const auto&) {}, {f1, f2}))
                 .GetWeakPtr();
  }

  ASSERT_TRUE(weak_f);
  weak_f->Then([&](std::vector<int>) { FAIL(); });
  f1->Complete(42);
  EXPECT_FALSE(weak_f);
}

TEST_F(FutureTest, WaitWithTimeoutReleasesReturnedFutureOnTimeout) {
  async::TestLoop loop;
  fxl::WeakPtr<Future<std::vector<int>>> weak_f;

  {
    auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
    weak_f = weak_factory(WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
                                          loop.dispatcher(), {}, [](const auto&) {}, {f1}))
                 .GetWeakPtr();
  }

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

TEST_F(FutureTest, Completer) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  auto completer = f->Completer();
  completer(5);

  AsyncExpectations async_expectations;

  f->Then([&](int i) {
    EXPECT_EQ(i, 5);
    async_expectations.Signal();
  });

  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, AsyncMap) {
  auto future = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  AsyncExpectations async_expectations;

  future
      ->AsyncMap([&](int i) {
        EXPECT_EQ(i, 10);
        async_expectations.Signal();

        auto f = Future<std::string>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
        f->Complete(std::to_string(i * 2));
        return f;
      })
      ->AsyncMap([&](std::string s) {
        EXPECT_EQ(s, "20");
        async_expectations.Signal();

        auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("3"));
        f->Complete(std::stoi(s));
        return f;
      })
      ->Then([&](int i) {
        EXPECT_EQ(i, 20);
        async_expectations.Signal();
      });

  future->Complete(10);

  EXPECT_EQ(3, async_expectations.count());
}

TEST_F(FutureTest, Map) {
  auto f = Future<int>::Create(__PRETTY_FUNCTION__);

  AsyncExpectations async_expectations;

  f->Map([&](int i) {
     EXPECT_EQ(i, 10);
     async_expectations.Signal();

     return std::to_string(i * 2);
   })
      ->Map([&](std::string s) {
        EXPECT_EQ(s, "20");
        async_expectations.Signal();

        return std::stoi(s);
      })
      ->Then([&](int i) {
        EXPECT_EQ(i, 20);
        async_expectations.Signal();
      });

  f->Complete(10);

  EXPECT_EQ(3, async_expectations.count());
}

TEST_F(FutureTest, MapToTuple) {
  float fresult;
  std::string sresult;

  auto f1 = Future<int>::Create(__PRETTY_FUNCTION__);
  FuturePtr<float, std::string> f2 =
      f1->Map([](int i) { return std::make_tuple(i / 2.f, std::to_string(i)); });

  f2->Then([&](float fvalue, const std::string& svalue) {
    fresult = fvalue;
    sresult = std::move(svalue);
  });

  f1->Complete(3);

  EXPECT_EQ(1.5f, fresult);
  EXPECT_EQ("3", sresult);
}

TEST_F(FutureTest, WeakMapToTuple) {
  // Similar to WeakMap(), but with tuples, like MapToTuple.
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);

  auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  // First let everything run.
  AsyncExpectations async_expectations;
  f->Map([&](int i) {
     async_expectations.Signal();
     return std::make_tuple(42, "the answer");
   })
      ->WeakMap(factory.GetWeakPtr(),
                [&](int i, const std::string& svalue) {
                  async_expectations.Signal();
                  return std::make_tuple(i + 2, std::to_string(i) + " was " + svalue);
                })
      ->Then([&](int i, const std::string& svalue) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(3, async_expectations.count());

  // Now invalidate it.
  f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
  async_expectations.Reset();
  f->Map([&](int i) {
     async_expectations.Signal();
     factory.InvalidateWeakPtrs();
     return std::make_tuple(42, "the answer");
   })
      ->WeakMap(factory.GetWeakPtr(),
                [&](int i, const std::string& svalue) {
                  async_expectations.Signal();
                  return std::make_tuple(i + 2, std::to_string(i) + " was " + svalue);
                })
      ->Then([&](int i, const std::string& svalue) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(1, async_expectations.count());
}

TEST_F(FutureTest, WeakAsyncMapToTuple) {
  // Similar to WeakMapToTuple(), but with WeakAsyncMap
  int data = 0;
  fxl::WeakPtrFactory<int> factory(&data);

  auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));

  // First let everything run.
  AsyncExpectations async_expectations;
  f->AsyncMap([&](int i) {
     async_expectations.Signal();
     return Future<float, std::string>::CreateCompleted(
         std::string(__PRETTY_FUNCTION__) + std::string("2"), 42, "the answer");
   })
      ->WeakAsyncMap(factory.GetWeakPtr(),
                     [&](int i, const std::string& svalue) {
                       async_expectations.Signal();
                       return Future<float, std::string>::CreateCompleted(
                           std::string(__PRETTY_FUNCTION__) + std::string("3"), i + 2,
                           std::to_string(i) + " was " + svalue);
                     })
      ->Then([&](int i, const std::string& svalue) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(3, async_expectations.count());

  // Now invalidate it.
  f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("4"));
  async_expectations.Reset();
  f->AsyncMap([&](int i) {
     async_expectations.Signal();
     factory.InvalidateWeakPtrs();
     return Future<float, std::string>::CreateCompleted(
         std::string(__PRETTY_FUNCTION__) + std::string("5"), 42, "the answer");
   })
      ->WeakAsyncMap(factory.GetWeakPtr(),
                     [&](int i, const std::string& svalue) {
                       async_expectations.Signal();
                       return Future<float, std::string>::CreateCompleted(
                           std::string(__PRETTY_FUNCTION__) + std::string("6"), i + 2,
                           std::to_string(i) + " was " + svalue);
                     })
      ->Then([&](int i, const std::string& svalue) { async_expectations.Signal(); });

  f->Complete(10);
  EXPECT_EQ(1, async_expectations.count());
}

// compile-time test
namespace MapToTupleTuple {
FuturePtr<std::tuple<float, std::string>> f =
    Future<int>::Create("MapToTupleTuple")->Map([](int i) {
      return std::make_tuple(std::make_tuple(i / 2.f, std::to_string(i)));
    });
}

TEST_F(FutureTest, trace_name) {
  auto f = Future<>::Create("test");
  EXPECT_EQ(f->trace_name(), "test");
}

TEST_F(FutureTest, ThenCallbackDestroysFuture) {
  struct S {
    FuturePtr<> f;
  };
  S* s = new S;

  AsyncExpectations async_expectations;

  s->f = Future<>::Create(__PRETTY_FUNCTION__);

  // Explicitly retain the subfuture returned by Then() to keep it alive. This
  // tests whether the original future will still complete its subfuture if the
  // original future is destroyed, but the subfuture is still kept alive. (That
  // should not happen, as per documentation for Then().)
  auto subfuture = s->f->Then([&] {
    delete s;
    async_expectations.Signal();
  });

  subfuture->Then([&] {
    // This lambda shouldn't be executed because s--and therefore s->f--was
    // deleted in the Then() callback above.
    async_expectations.Signal();
  });

  s->f->Complete();

  EXPECT_EQ(1, async_expectations.count());  // not 2!
}

}  // namespace
}  // namespace modular
