// Copyright 2019 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/android/java_handler_thread.h"

#include "base/synchronization/waitable_event.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/task_observer.h"
#include "base/test/android/java_handler_thread_helpers.h"
#include "base/test/bind.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

class JavaHandlerThreadForTest : public android::JavaHandlerThread {
 public:
  explicit JavaHandlerThreadForTest(
      const char* name,
      base::ThreadPriority priority = base::ThreadPriority::NORMAL)
      : android::JavaHandlerThread(name, priority) {}

  using android::JavaHandlerThread::state;
  using android::JavaHandlerThread::State;
};

class DummyTaskObserver : public TaskObserver {
 public:
  explicit DummyTaskObserver(int num_tasks)
      : num_tasks_started_(0), num_tasks_processed_(0), num_tasks_(num_tasks) {}

  DummyTaskObserver(int num_tasks, int num_tasks_started)
      : num_tasks_started_(num_tasks_started),
        num_tasks_processed_(0),
        num_tasks_(num_tasks) {}

  DummyTaskObserver(const DummyTaskObserver&) = delete;
  DummyTaskObserver& operator=(const DummyTaskObserver&) = delete;

  ~DummyTaskObserver() override = default;

  void WillProcessTask(const PendingTask& /* pending_task */,
                       bool /* was_blocked_or_low_priority */) override {
    num_tasks_started_++;
    EXPECT_LE(num_tasks_started_, num_tasks_);
    EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
  }

  void DidProcessTask(const PendingTask& pending_task) override {
    num_tasks_processed_++;
    EXPECT_LE(num_tasks_started_, num_tasks_);
    EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
  }

  int num_tasks_started() const { return num_tasks_started_; }
  int num_tasks_processed() const { return num_tasks_processed_; }

 private:
  int num_tasks_started_;
  int num_tasks_processed_;
  const int num_tasks_;
};

void PostNTasks(int posts_remaining) {
  if (posts_remaining > 1) {
    ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, BindOnce(&PostNTasks, posts_remaining - 1));
  }
}

}  // namespace

class JavaHandlerThreadTest : public ::testing::Test {};

void RunTest_AbortDontRunMoreTasks(bool delayed, bool init_java_first) {
  WaitableEvent test_done_event;
  std::unique_ptr<android::JavaHandlerThread> java_thread;
  if (init_java_first) {
    java_thread = android::JavaHandlerThreadHelpers::CreateJavaFirst();
  } else {
    java_thread = std::make_unique<android::JavaHandlerThread>(
        "JavaHandlerThreadForTesting from AbortDontRunMoreTasks");
  }
  java_thread->Start();
  java_thread->ListenForUncaughtExceptionsForTesting();

  auto target =
      BindOnce(&android::JavaHandlerThreadHelpers::ThrowExceptionAndAbort,
               &test_done_event);
  if (delayed) {
    java_thread->task_runner()->PostDelayedTask(FROM_HERE, std::move(target),
                                                Milliseconds(10));
  } else {
    java_thread->task_runner()->PostTask(FROM_HERE, std::move(target));
    java_thread->task_runner()->PostTask(FROM_HERE,
                                         MakeExpectedNotRunClosure(FROM_HERE));
  }
  test_done_event.Wait();
  java_thread->Stop();
  android::ScopedJavaLocalRef<jthrowable> exception =
      java_thread->GetUncaughtExceptionIfAny();
  ASSERT_TRUE(
      android::JavaHandlerThreadHelpers::IsExceptionTestException(exception));
}

TEST_F(JavaHandlerThreadTest, JavaExceptionAbort) {
  constexpr bool delayed = false;
  constexpr bool init_java_first = false;
  RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
}

TEST_F(JavaHandlerThreadTest, DelayedJavaExceptionAbort) {
  constexpr bool delayed = true;
  constexpr bool init_java_first = false;
  RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
}

TEST_F(JavaHandlerThreadTest, JavaExceptionAbortInitJavaFirst) {
  constexpr bool delayed = false;
  constexpr bool init_java_first = true;
  RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
}

TEST_F(JavaHandlerThreadTest, RunTasksWhileShuttingDownJavaThread) {
  const int kNumPosts = 6;
  DummyTaskObserver observer(kNumPosts, 1);

  auto java_thread = std::make_unique<JavaHandlerThreadForTest>("test");
  java_thread->Start();

  sequence_manager::internal::SequenceManagerImpl* sequence_manager =
      static_cast<sequence_manager::internal::SequenceManagerImpl*>(
          java_thread->state()->sequence_manager.get());

  java_thread->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        sequence_manager->AddTaskObserver(&observer);
        ThreadTaskRunnerHandle::Get()->PostDelayedTask(
            FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), Days(1));
        java_thread->StopSequenceManagerForTesting();
        PostNTasks(kNumPosts);
      }));

  java_thread->JoinForTesting();
  java_thread.reset();

  EXPECT_EQ(kNumPosts, observer.num_tasks_started());
  EXPECT_EQ(kNumPosts, observer.num_tasks_processed());
}

}  // namespace base
