/*
 * Copyright 2016 The Chromium OS 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 "cros-camera/future.h"

#include <base/at_exit.h>
#include <base/threading/thread.h>
#include <base/time/time.h>
#include <gtest/gtest.h>

#include "cros-camera/common.h"

namespace cros {

class FutureTest : public ::testing::Test {
 public:
  FutureTest() : thread_("Test Thread") {}

  virtual void SetUp() {
    if (!thread_.StartWithOptions(
            base::Thread::Options(base::MessagePumpType::IO, 0))) {
      LOGF(ERROR) << "Test thread failed to start";
      exit(-1);
    }
    thread_.WaitUntilThreadStarted();
  }

  virtual void TearDown() { thread_.Stop(); }

  void SignalCallback(const base::Callback<void()>& cb) { cb.Run(); }

  template <typename T>
  void SignalCallbackWith(const base::Callback<void(T)>& cb, T val) {
    cb.Run(std::move(val));
  }

  void CancelCallback() { relay_.CancelAllFutures(); }

 protected:
  base::Thread thread_;

  CancellationRelay relay_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FutureTest);
};

TEST_F(FutureTest, WaitTest) {
  // Normal signal-wait scenario.  The future wait should return true.

  // The future is signalled after being waited on.
  auto future = Future<void>::Create(&relay_);
  thread_.task_runner()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FutureTest::SignalCallback, base::Unretained(this),
                 cros::GetFutureCallback(future)),
      base::TimeDelta::FromMilliseconds(2000));
  ASSERT_TRUE(future->Wait());

  // Subsequent wait to a signalled future should return true.
  ASSERT_TRUE(future->Wait());

  // The future is signalled before being waited on.
  future = Future<void>::Create(&relay_);
  future->Set();
  ASSERT_TRUE(future->Wait());
}

TEST_F(FutureTest, GetTest) {
  auto future = Future<int>::Create(&relay_);
  thread_.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&FutureTest::SignalCallbackWith<int>, base::Unretained(this),
                 cros::GetFutureCallback(future), 42));
  ASSERT_EQ(future->Get(), 42);
}

TEST_F(FutureTest, GetMoveOnlyTest) {
  auto future = Future<std::unique_ptr<int>>::Create(&relay_);
  auto ptr = std::make_unique<int>(42);
  thread_.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&FutureTest::SignalCallbackWith<std::unique_ptr<int>>,
                 base::Unretained(this), cros::GetFutureCallback(future),
                 base::Passed(std::move(ptr))));
  ptr = future->Get();
  ASSERT_EQ(*ptr, 42);
}

TEST_F(FutureTest, TimeoutTest) {
  // A future wait should return false because of time-out if it's not
  // signalled.
  auto future = Future<void>::Create(&relay_);
  base::TimeTicks start = base::TimeTicks::Now();
  ASSERT_FALSE(future->Wait(1000));
  ASSERT_GE(base::TimeTicks::Now() - start,
            base::TimeDelta::FromMilliseconds(1000));
  // Subsequent wait to a timed-out future can time out again.
  ASSERT_FALSE(future->Wait(1000));
  // Now we signal the future and the final wait should return true.
  thread_.task_runner()->PostTask(
      FROM_HERE, base::Bind(&FutureTest::SignalCallback, base::Unretained(this),
                            cros::GetFutureCallback(future)));
  ASSERT_TRUE(future->Wait());
}

TEST_F(FutureTest, CancelTest) {
  // A future wait should return false if it's cancelled.  The future is
  // cancelled before it's being waited on.
  auto future = Future<void>::Create(&relay_);
  relay_.CancelAllFutures();
  ASSERT_FALSE(future->Wait());
  // Subsequent wait to a cancelled future should return false.
  ASSERT_FALSE(future->Wait());

  // A future wait should return false if the relay_.CancelAllFutures() has been
  // called.
  future = Future<void>::Create(&relay_);
  thread_.task_runner()->PostTask(
      FROM_HERE, base::Bind(&FutureTest::SignalCallback, base::Unretained(this),
                            cros::GetFutureCallback(future)));
  ASSERT_FALSE(future->Wait());
}

TEST_F(FutureTest, DelayedCancelTest) {
  // A future wait should return false if it's cancelled.  The future is
  // cancelled after it's being waited on.
  auto future = Future<void>::Create(&relay_);
  thread_.task_runner()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FutureTest::CancelCallback, base::Unretained(this)),
      base::TimeDelta::FromMilliseconds(2000));
  ASSERT_FALSE(future->Wait());
}

TEST_F(FutureTest, FutureRefcountTest) {
  // Create a future and then immediately cancel it via CancellationRelay.
  // Schedule a SignalCallback on another thread with 2 seconds delay such that
  // the callback will run after the main thread has terminated.
  // The wait on main thread should return false immediately.
  // The SignalCallback should successfully run in another thread even after
  // main thread has terminated.
  auto future = Future<void>::Create(&relay_);
  relay_.CancelAllFutures();
  thread_.task_runner()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FutureTest::SignalCallback, base::Unretained(this),
                 cros::GetFutureCallback(future)),
      base::TimeDelta::FromMilliseconds(2000));
  ASSERT_FALSE(future->Wait());
}

}  // namespace cros

int main(int argc, char** argv) {
  base::AtExitManager exit_manager;
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
