// Copyright 2018 The Chromium 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 "base/task/common/operations_controller.h"

#include <atomic>
#include <cstdint>
#include <utility>

#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace internal {
namespace {

class ScopedShutdown {
 public:
  ScopedShutdown(OperationsController* controller) : controller_(*controller) {}
  ~ScopedShutdown() { controller_.ShutdownAndWaitForZeroOperations(); }

 private:
  OperationsController& controller_;
};

TEST(OperationsControllerTest, CanBeDestroyedWithoutWaiting) {
  OperationsController controller;
}

TEST(OperationsControllerTest, CanShutdownIfNotStarted) {
  OperationsController controller;

  controller.ShutdownAndWaitForZeroOperations();
}

TEST(OperationsControllerTest, FailsToBeginWhenNotStarted) {
  OperationsController controller;

  auto operation_token = controller.TryBeginOperation();

  EXPECT_FALSE(operation_token);
}

TEST(OperationsControllerTest, CanShutdownAfterTryCallsIfNotStarted) {
  OperationsController controller;
  auto operation_token = controller.TryBeginOperation();
  ASSERT_FALSE(operation_token);

  controller.ShutdownAndWaitForZeroOperations();
}

TEST(OperationsControllerTest,
     StartAcceptingOperationsReturnsFalseIfNoRejectedBeginAttempts) {
  OperationsController controller;
  ScopedShutdown cleanup(&controller);

  EXPECT_FALSE(controller.StartAcceptingOperations());
}

TEST(OperationsControllerTest,
     StartAcceptingOperationsReturnsTrueIfFailedBeginAttempts) {
  OperationsController controller;
  ScopedShutdown cleanup(&controller);

  auto operation_token = controller.TryBeginOperation();
  ASSERT_FALSE(operation_token);

  EXPECT_TRUE(controller.StartAcceptingOperations());
}

TEST(OperationsControllerTest, SuccesfulBeginReturnsValidScopedObject) {
  OperationsController controller;
  ScopedShutdown cleanup(&controller);
  controller.StartAcceptingOperations();

  auto operation_token = controller.TryBeginOperation();

  EXPECT_TRUE(operation_token);
}

TEST(OperationsControllerTest, BeginFailsAfterShutdown) {
  OperationsController controller;
  controller.StartAcceptingOperations();

  controller.ShutdownAndWaitForZeroOperations();
  auto operation_token = controller.TryBeginOperation();

  EXPECT_FALSE(operation_token);
}

TEST(OperationsControllerTest, ScopedOperationsControllerIsMoveConstructible) {
  OperationsController controller;
  ScopedShutdown cleanup(&controller);

  controller.StartAcceptingOperations();
  auto operation_token_1 = controller.TryBeginOperation();
  auto operation_token_2 = std::move(operation_token_1);

  EXPECT_FALSE(operation_token_1);
  EXPECT_TRUE(operation_token_2);
}

// Dummy SimpleThread implementation that periodically begins and ends
// operations until one of them fails.
class TestThread : public SimpleThread {
 public:
  explicit TestThread(OperationsController* ref_controller,
                      std::atomic<bool>* started,
                      std::atomic<int32_t>* thread_counter)
      : SimpleThread("TestThread"),
        controller_(*ref_controller),
        started_(*started),
        thread_counter_(*thread_counter) {}
  void Run() override {
    thread_counter_.fetch_add(1, std::memory_order_relaxed);
    while (true) {
      PlatformThread::YieldCurrentThread();
      bool was_started = started_.load(std::memory_order_relaxed);
      std::vector<OperationsController::OperationToken> tokens;
      for (int i = 0; i < 100; ++i) {
        tokens.push_back(controller_.TryBeginOperation());
      }
      if (!was_started)
        continue;
      if (std::any_of(tokens.begin(), tokens.end(),
                      [](const auto& token) { return !token; })) {
        break;
      }
    }
  }

 private:
  OperationsController& controller_;
  std::atomic<bool>& started_;
  std::atomic<int32_t>& thread_counter_;
};

TEST(OperationsControllerTest, BeginsFromMultipleThreads) {
  constexpr int32_t kNumThreads = 10;
  for (int32_t i = 0; i < 10; ++i) {
    OperationsController ref_controller;
    std::atomic<bool> started(false);
    std::atomic<int32_t> running_threads(0);
    std::vector<std::unique_ptr<TestThread>> threads;
    for (int j = 0; j < kNumThreads; ++j) {
      threads.push_back(std::make_unique<TestThread>(&ref_controller, &started,
                                                     &running_threads));
      threads.back()->Start();
    }

    // Make sure all threads are running.
    while (running_threads.load(std::memory_order_relaxed) != kNumThreads) {
      PlatformThread::YieldCurrentThread();
    }

    // Wait a bit before starting to try to introduce races.
    constexpr TimeDelta kRaceInducingTimeout = TimeDelta::FromMicroseconds(50);
    PlatformThread::Sleep(kRaceInducingTimeout);

    ref_controller.StartAcceptingOperations();
    // Signal threads to terminate on TryBeginOperation() failures
    started.store(true, std::memory_order_relaxed);

    // Let the test run for a while before shuting down.
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(5));
    ref_controller.ShutdownAndWaitForZeroOperations();
    for (const auto& t : threads) {
      t->Join();
    }
  }
}

}  // namespace
}  // namespace internal
}  // namespace base
