// Copyright 2015 the V8 project 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/base/atomicops.h"
#include "src/base/platform/platform.h"
#include "src/cancelable-task.h"
#include "testing/gtest/include/gtest/gtest.h"


namespace v8 {
namespace internal {

namespace {

class TestTask : public Task, public Cancelable {
 public:
  enum Mode { kDoNothing, kWaitTillCanceledAgain, kCheckNotRun };

  TestTask(CancelableTaskManager* parent, base::AtomicWord* result,
           Mode mode = kDoNothing)
      : Cancelable(parent), result_(result), mode_(mode) {}

  // Task overrides.
  void Run() final {
    if (TryRun()) {
      RunInternal();
    }
  }

 private:
  void RunInternal() {
    base::Release_Store(result_, id());

    switch (mode_) {
      case kWaitTillCanceledAgain:
        // Simple busy wait until the main thread tried to cancel.
        while (CancelAttempts() == 0) {
        }
        break;
      case kCheckNotRun:
        // Check that we never execute {RunInternal}.
        EXPECT_TRUE(false);
        break;
      default:
        break;
    }
  }

  base::AtomicWord* result_;
  Mode mode_;
};


class SequentialRunner {
 public:
  explicit SequentialRunner(TestTask* task) : task_(task) {}

  void Run() {
    task_->Run();
    delete task_;
  }

 private:
  TestTask* task_;
};


class ThreadedRunner final : public base::Thread {
 public:
  explicit ThreadedRunner(TestTask* task)
      : Thread(Options("runner thread")), task_(task) {}

  virtual void Run() {
    task_->Run();
    delete task_;
  }

 private:
  TestTask* task_;
};


typedef base::AtomicWord ResultType;


intptr_t GetValue(ResultType* result) { return base::Acquire_Load(result); }

}  // namespace


TEST(CancelableTask, EmptyCancelableTaskManager) {
  CancelableTaskManager manager;
  manager.CancelAndWait();
}


TEST(CancelableTask, SequentialCancelAndWait) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  SequentialRunner runner1(
      new TestTask(&manager, &result1, TestTask::kCheckNotRun));
  EXPECT_EQ(GetValue(&result1), 0);
  manager.CancelAndWait();
  EXPECT_EQ(GetValue(&result1), 0);
  runner1.Run();  // Run to avoid leaking the Task.
  EXPECT_EQ(GetValue(&result1), 0);
}


TEST(CancelableTask, SequentialMultipleTasks) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  ResultType result2 = 0;
  TestTask* task1 = new TestTask(&manager, &result1);
  TestTask* task2 = new TestTask(&manager, &result2);
  SequentialRunner runner1(task1);
  SequentialRunner runner2(task2);
  EXPECT_EQ(task1->id(), 1u);
  EXPECT_EQ(task2->id(), 2u);

  EXPECT_EQ(GetValue(&result1), 0);
  runner1.Run();  // Don't touch task1 after running it.
  EXPECT_EQ(GetValue(&result1), 1);

  EXPECT_EQ(GetValue(&result2), 0);
  runner2.Run();  // Don't touch task2 after running it.
  EXPECT_EQ(GetValue(&result2), 2);

  manager.CancelAndWait();
  EXPECT_FALSE(manager.TryAbort(1));
  EXPECT_FALSE(manager.TryAbort(2));
}


TEST(CancelableTask, ThreadedMultipleTasksStarted) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  ResultType result2 = 0;
  TestTask* task1 =
      new TestTask(&manager, &result1, TestTask::kWaitTillCanceledAgain);
  TestTask* task2 =
      new TestTask(&manager, &result2, TestTask::kWaitTillCanceledAgain);
  ThreadedRunner runner1(task1);
  ThreadedRunner runner2(task2);
  runner1.Start();
  runner2.Start();
  // Busy wait on result to make sure both tasks are done.
  while ((GetValue(&result1) == 0) || (GetValue(&result2) == 0)) {
  }
  manager.CancelAndWait();
  runner1.Join();
  runner2.Join();
  EXPECT_EQ(GetValue(&result1), 1);
  EXPECT_EQ(GetValue(&result2), 2);
}


TEST(CancelableTask, ThreadedMultipleTasksNotRun) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  ResultType result2 = 0;
  TestTask* task1 = new TestTask(&manager, &result1, TestTask::kCheckNotRun);
  TestTask* task2 = new TestTask(&manager, &result2, TestTask::kCheckNotRun);
  ThreadedRunner runner1(task1);
  ThreadedRunner runner2(task2);
  manager.CancelAndWait();
  // Tasks are canceled, hence the runner will bail out and not update result.
  runner1.Start();
  runner2.Start();
  runner1.Join();
  runner2.Join();
  EXPECT_EQ(GetValue(&result1), 0);
  EXPECT_EQ(GetValue(&result2), 0);
}


TEST(CancelableTask, RemoveBeforeCancelAndWait) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  TestTask* task1 = new TestTask(&manager, &result1, TestTask::kCheckNotRun);
  ThreadedRunner runner1(task1);
  CancelableTaskManager::Id id = task1->id();
  EXPECT_EQ(id, 1u);
  EXPECT_TRUE(manager.TryAbort(id));
  runner1.Start();
  runner1.Join();
  manager.CancelAndWait();
  EXPECT_EQ(GetValue(&result1), 0);
}


TEST(CancelableTask, RemoveAfterCancelAndWait) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  TestTask* task1 = new TestTask(&manager, &result1);
  ThreadedRunner runner1(task1);
  CancelableTaskManager::Id id = task1->id();
  EXPECT_EQ(id, 1u);
  runner1.Start();
  runner1.Join();
  manager.CancelAndWait();
  EXPECT_FALSE(manager.TryAbort(id));
  EXPECT_EQ(GetValue(&result1), 1);
}


TEST(CancelableTask, RemoveUnmanagedId) {
  CancelableTaskManager manager;
  EXPECT_FALSE(manager.TryAbort(1));
  EXPECT_FALSE(manager.TryAbort(2));
  manager.CancelAndWait();
  EXPECT_FALSE(manager.TryAbort(1));
  EXPECT_FALSE(manager.TryAbort(3));
}

TEST(CancelableTask, EmptyTryAbortAll) {
  CancelableTaskManager manager;
  EXPECT_EQ(manager.TryAbortAll(), CancelableTaskManager::kTaskRemoved);
}

TEST(CancelableTask, ThreadedMultipleTasksNotRunTryAbortAll) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  ResultType result2 = 0;
  TestTask* task1 = new TestTask(&manager, &result1, TestTask::kCheckNotRun);
  TestTask* task2 = new TestTask(&manager, &result2, TestTask::kCheckNotRun);
  ThreadedRunner runner1(task1);
  ThreadedRunner runner2(task2);
  EXPECT_EQ(manager.TryAbortAll(), CancelableTaskManager::kTaskAborted);
  // Tasks are canceled, hence the runner will bail out and not update result.
  runner1.Start();
  runner2.Start();
  runner1.Join();
  runner2.Join();
  EXPECT_EQ(GetValue(&result1), 0);
  EXPECT_EQ(GetValue(&result2), 0);
}

TEST(CancelableTask, ThreadedMultipleTasksStartedTryAbortAll) {
  CancelableTaskManager manager;
  ResultType result1 = 0;
  ResultType result2 = 0;
  TestTask* task1 =
      new TestTask(&manager, &result1, TestTask::kWaitTillCanceledAgain);
  TestTask* task2 =
      new TestTask(&manager, &result2, TestTask::kWaitTillCanceledAgain);
  ThreadedRunner runner1(task1);
  ThreadedRunner runner2(task2);
  runner1.Start();
  // Busy wait on result to make sure task1 is done.
  while (GetValue(&result1) == 0) {
  }
  EXPECT_EQ(manager.TryAbortAll(), CancelableTaskManager::kTaskRunning);
  runner2.Start();
  runner1.Join();
  runner2.Join();
  EXPECT_EQ(GetValue(&result1), 1);
  EXPECT_EQ(GetValue(&result2), 0);
}

}  // namespace internal
}  // namespace v8
