// Copyright 2014 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/bind.h"
#include "base/bind_helpers.h"
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"

#if defined(OS_ANDROID)
#include "base/android/java_handler_thread.h"
#include "starboard/types.h"
#endif

namespace base {

class ScheduleWorkTest : public testing::Test {
 public:
  ScheduleWorkTest() : counter_(0) {}

  void SetUp() override {
    if (base::ThreadTicks::IsSupported())
      base::ThreadTicks::WaitUntilInitialized();
  }

  void Increment(uint64_t amount) { counter_ += amount; }

  void Schedule(int index) {
    base::TimeTicks start = base::TimeTicks::Now();
    base::ThreadTicks thread_start;
    if (ThreadTicks::IsSupported())
      thread_start = base::ThreadTicks::Now();
    base::TimeDelta minimum = base::TimeDelta::Max();
    base::TimeDelta maximum = base::TimeDelta();
    base::TimeTicks now, lastnow = start;
    uint64_t schedule_calls = 0u;
    do {
      for (size_t i = 0; i < kBatchSize; ++i) {
        target_message_loop()->ScheduleWork();
        schedule_calls++;
      }
      now = base::TimeTicks::Now();
      base::TimeDelta laptime = now - lastnow;
      lastnow = now;
      minimum = std::min(minimum, laptime);
      maximum = std::max(maximum, laptime);
    } while (now - start < base::TimeDelta::FromSeconds(kTargetTimeSec));

    scheduling_times_[index] = now - start;
    if (ThreadTicks::IsSupported())
      scheduling_thread_times_[index] =
          base::ThreadTicks::Now() - thread_start;
    min_batch_times_[index] = minimum;
    max_batch_times_[index] = maximum;
    target_message_loop()->task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ScheduleWorkTest::Increment,
                                  base::Unretained(this), schedule_calls));
  }

  void ScheduleWork(MessageLoop::Type target_type, int num_scheduling_threads) {
#if defined(OS_ANDROID)
    if (target_type == MessageLoop::TYPE_JAVA) {
      java_thread_.reset(new android::JavaHandlerThread("target"));
      java_thread_->Start();
    } else
#endif
    {
      target_.reset(new Thread("target"));
      target_->StartWithOptions(Thread::Options(target_type, 0u));

      // Without this, it's possible for the scheduling threads to start and run
      // before the target thread. In this case, the scheduling threads will
      // call target_message_loop()->ScheduleWork(), which dereferences the
      // loop's message pump, which is only created after the target thread has
      // finished starting.
      target_->WaitUntilThreadStarted();
    }

    std::vector<std::unique_ptr<Thread>> scheduling_threads;
    scheduling_times_.reset(new base::TimeDelta[num_scheduling_threads]);
    scheduling_thread_times_.reset(new base::TimeDelta[num_scheduling_threads]);
    min_batch_times_.reset(new base::TimeDelta[num_scheduling_threads]);
    max_batch_times_.reset(new base::TimeDelta[num_scheduling_threads]);

    for (int i = 0; i < num_scheduling_threads; ++i) {
      scheduling_threads.push_back(std::make_unique<Thread>("posting thread"));
      scheduling_threads[i]->Start();
    }

    for (int i = 0; i < num_scheduling_threads; ++i) {
      scheduling_threads[i]->task_runner()->PostTask(
          FROM_HERE, base::BindOnce(&ScheduleWorkTest::Schedule,
                                    base::Unretained(this), i));
    }

    for (int i = 0; i < num_scheduling_threads; ++i) {
      scheduling_threads[i]->Stop();
    }
#if defined(OS_ANDROID)
    if (target_type == MessageLoop::TYPE_JAVA) {
      java_thread_->Stop();
      java_thread_.reset();
    } else
#endif
    {
      target_->Stop();
      target_.reset();
    }
    base::TimeDelta total_time;
    base::TimeDelta total_thread_time;
    base::TimeDelta min_batch_time = base::TimeDelta::Max();
    base::TimeDelta max_batch_time = base::TimeDelta();
    for (int i = 0; i < num_scheduling_threads; ++i) {
      total_time += scheduling_times_[i];
      total_thread_time += scheduling_thread_times_[i];
      min_batch_time = std::min(min_batch_time, min_batch_times_[i]);
      max_batch_time = std::max(max_batch_time, max_batch_times_[i]);
    }
    std::string trace = StringPrintf(
        "%d_threads_scheduling_to_%s_pump",
        num_scheduling_threads,
        target_type == MessageLoop::TYPE_IO
            ? "io"
            : (target_type == MessageLoop::TYPE_UI ? "ui" : "default"));
    perf_test::PrintResult(
        "task",
        "",
        trace,
        total_time.InMicroseconds() / static_cast<double>(counter_),
        "us/task",
        true);
    perf_test::PrintResult(
        "task",
        "_min_batch_time",
        trace,
        min_batch_time.InMicroseconds() / static_cast<double>(kBatchSize),
        "us/task",
        false);
    perf_test::PrintResult(
        "task",
        "_max_batch_time",
        trace,
        max_batch_time.InMicroseconds() / static_cast<double>(kBatchSize),
        "us/task",
        false);
    if (ThreadTicks::IsSupported()) {
      perf_test::PrintResult(
          "task",
          "_thread_time",
          trace,
          total_thread_time.InMicroseconds() / static_cast<double>(counter_),
          "us/task",
          true);
    }
  }

  MessageLoop* target_message_loop() {
#if defined(OS_ANDROID)
    if (java_thread_)
      return java_thread_->message_loop();
#endif
    return target_->message_loop();
  }

 private:
  std::unique_ptr<Thread> target_;
#if defined(OS_ANDROID)
  std::unique_ptr<android::JavaHandlerThread> java_thread_;
#endif
  std::unique_ptr<base::TimeDelta[]> scheduling_times_;
  std::unique_ptr<base::TimeDelta[]> scheduling_thread_times_;
  std::unique_ptr<base::TimeDelta[]> min_batch_times_;
  std::unique_ptr<base::TimeDelta[]> max_batch_times_;
  uint64_t counter_;

  static const size_t kTargetTimeSec = 5;
  static const size_t kBatchSize = 1000;
};

TEST_F(ScheduleWorkTest, ThreadTimeToIOFromOneThread) {
  ScheduleWork(MessageLoop::TYPE_IO, 1);
}

TEST_F(ScheduleWorkTest, ThreadTimeToIOFromTwoThreads) {
  ScheduleWork(MessageLoop::TYPE_IO, 2);
}

TEST_F(ScheduleWorkTest, ThreadTimeToIOFromFourThreads) {
  ScheduleWork(MessageLoop::TYPE_IO, 4);
}

TEST_F(ScheduleWorkTest, ThreadTimeToUIFromOneThread) {
  ScheduleWork(MessageLoop::TYPE_UI, 1);
}

TEST_F(ScheduleWorkTest, ThreadTimeToUIFromTwoThreads) {
  ScheduleWork(MessageLoop::TYPE_UI, 2);
}

TEST_F(ScheduleWorkTest, ThreadTimeToUIFromFourThreads) {
  ScheduleWork(MessageLoop::TYPE_UI, 4);
}

TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromOneThread) {
  ScheduleWork(MessageLoop::TYPE_DEFAULT, 1);
}

TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromTwoThreads) {
  ScheduleWork(MessageLoop::TYPE_DEFAULT, 2);
}

TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromFourThreads) {
  ScheduleWork(MessageLoop::TYPE_DEFAULT, 4);
}

#if defined(OS_ANDROID)
TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromOneThread) {
  ScheduleWork(MessageLoop::TYPE_JAVA, 1);
}

TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromTwoThreads) {
  ScheduleWork(MessageLoop::TYPE_JAVA, 2);
}

TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromFourThreads) {
  ScheduleWork(MessageLoop::TYPE_JAVA, 4);
}
#endif

}  // namespace base
