// Copyright 2013 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/libplatform/default-platform.h"

#include <algorithm>
#include <queue>

#include "include/libplatform/libplatform.h"
#include "src/base/debug/stack_trace.h"
#include "src/base/logging.h"
#include "src/base/page-allocator.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"
#include "src/base/sys-info.h"
#include "src/libplatform/default-foreground-task-runner.h"
#include "src/libplatform/default-job.h"
#include "src/libplatform/default-worker-threads-task-runner.h"

namespace v8 {
namespace platform {

namespace {

void PrintStackTrace() {
  v8::base::debug::StackTrace trace;
  trace.Print();
  // Avoid dumping duplicate stack trace on abort signal.
  v8::base::debug::DisableSignalStackDump();
}

}  // namespace

std::unique_ptr<v8::Platform> NewDefaultPlatform(
    int thread_pool_size, IdleTaskSupport idle_task_support,
    InProcessStackDumping in_process_stack_dumping,
    std::unique_ptr<v8::TracingController> tracing_controller) {
  if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
    v8::base::debug::EnableInProcessStackDumping();
  }
  auto platform = std::make_unique<DefaultPlatform>(
      thread_pool_size, idle_task_support, std::move(tracing_controller));
  platform->EnsureBackgroundTaskRunnerInitialized();
  return platform;
}

V8_PLATFORM_EXPORT std::unique_ptr<JobHandle> NewDefaultJobHandle(
    Platform* platform, TaskPriority priority,
    std::unique_ptr<JobTask> job_task, size_t num_worker_threads) {
  return std::make_unique<DefaultJobHandle>(std::make_shared<DefaultJobState>(
      platform, std::move(job_task), priority, num_worker_threads));
}

bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
                     MessageLoopBehavior behavior) {
  return static_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate,
                                                                  behavior);
}

void RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
                  double idle_time_in_seconds) {
  static_cast<DefaultPlatform*>(platform)->RunIdleTasks(isolate,
                                                        idle_time_in_seconds);
}

void SetTracingController(
    v8::Platform* platform,
    v8::platform::tracing::TracingController* tracing_controller) {
  static_cast<DefaultPlatform*>(platform)->SetTracingController(
      std::unique_ptr<v8::TracingController>(tracing_controller));
}

void NotifyIsolateShutdown(v8::Platform* platform, Isolate* isolate) {
  static_cast<DefaultPlatform*>(platform)->NotifyIsolateShutdown(isolate);
}

namespace {
constexpr int kMaxThreadPoolSize = 16;

int GetActualThreadPoolSize(int thread_pool_size) {
  DCHECK_GE(thread_pool_size, 0);
  if (thread_pool_size < 1) {
    thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
  }
  return std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
}
}  // namespace

DefaultPlatform::DefaultPlatform(
    int thread_pool_size, IdleTaskSupport idle_task_support,
    std::unique_ptr<v8::TracingController> tracing_controller)
    : thread_pool_size_(GetActualThreadPoolSize(thread_pool_size)),
      idle_task_support_(idle_task_support),
      tracing_controller_(std::move(tracing_controller)),
      page_allocator_(std::make_unique<v8::base::PageAllocator>()) {
  if (!tracing_controller_) {
    tracing::TracingController* controller = new tracing::TracingController();
#if !defined(V8_USE_PERFETTO)
    controller->Initialize(nullptr);
#endif
    tracing_controller_.reset(controller);
  }
}

DefaultPlatform::~DefaultPlatform() {
  base::MutexGuard guard(&lock_);
  if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
  for (const auto& it : foreground_task_runner_map_) {
    it.second->Terminate();
  }
}

namespace {

double DefaultTimeFunction() {
  return base::TimeTicks::HighResolutionNow().ToInternalValue() /
         static_cast<double>(base::Time::kMicrosecondsPerSecond);
}

}  // namespace

void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
  base::MutexGuard guard(&lock_);
  if (!worker_threads_task_runner_) {
    worker_threads_task_runner_ =
        std::make_shared<DefaultWorkerThreadsTaskRunner>(
            thread_pool_size_, time_function_for_testing_
                                   ? time_function_for_testing_
                                   : DefaultTimeFunction);
  }
}

void DefaultPlatform::SetTimeFunctionForTesting(
    DefaultPlatform::TimeFunction time_function) {
  base::MutexGuard guard(&lock_);
  time_function_for_testing_ = time_function;
  // The time function has to be right after the construction of the platform.
  DCHECK(foreground_task_runner_map_.empty());
}

bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate,
                                      MessageLoopBehavior wait_for_work) {
  bool failed_result = wait_for_work == MessageLoopBehavior::kWaitForWork;
  std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
  {
    base::MutexGuard guard(&lock_);
    auto it = foreground_task_runner_map_.find(isolate);
    if (it == foreground_task_runner_map_.end()) return failed_result;
    task_runner = it->second;
  }

  std::unique_ptr<Task> task = task_runner->PopTaskFromQueue(wait_for_work);
  if (!task) return failed_result;

  DefaultForegroundTaskRunner::RunTaskScope scope(task_runner);
  task->Run();
  return true;
}

void DefaultPlatform::RunIdleTasks(v8::Isolate* isolate,
                                   double idle_time_in_seconds) {
  DCHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
  std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
  {
    base::MutexGuard guard(&lock_);
    if (foreground_task_runner_map_.find(isolate) ==
        foreground_task_runner_map_.end()) {
      return;
    }
    task_runner = foreground_task_runner_map_[isolate];
  }
  double deadline_in_seconds =
      MonotonicallyIncreasingTime() + idle_time_in_seconds;

  while (deadline_in_seconds > MonotonicallyIncreasingTime()) {
    std::unique_ptr<IdleTask> task = task_runner->PopTaskFromIdleQueue();
    if (!task) return;
    DefaultForegroundTaskRunner::RunTaskScope scope(task_runner);
    task->Run(deadline_in_seconds);
  }
}

std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
    v8::Isolate* isolate) {
  base::MutexGuard guard(&lock_);
  if (foreground_task_runner_map_.find(isolate) ==
      foreground_task_runner_map_.end()) {
    foreground_task_runner_map_.insert(std::make_pair(
        isolate, std::make_shared<DefaultForegroundTaskRunner>(
                     idle_task_support_, time_function_for_testing_
                                             ? time_function_for_testing_
                                             : DefaultTimeFunction)));
  }
  return foreground_task_runner_map_[isolate];
}

void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
  EnsureBackgroundTaskRunnerInitialized();
  worker_threads_task_runner_->PostTask(std::move(task));
}

void DefaultPlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
                                                double delay_in_seconds) {
  EnsureBackgroundTaskRunnerInitialized();
  worker_threads_task_runner_->PostDelayedTask(std::move(task),
                                               delay_in_seconds);
}

bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
  return idle_task_support_ == IdleTaskSupport::kEnabled;
}

std::unique_ptr<JobHandle> DefaultPlatform::PostJob(
    TaskPriority priority, std::unique_ptr<JobTask> job_task) {
  size_t num_worker_threads = NumberOfWorkerThreads();
  if (priority == TaskPriority::kBestEffort && num_worker_threads > 2) {
    num_worker_threads = 2;
  }
  return NewDefaultJobHandle(this, priority, std::move(job_task),
                             num_worker_threads);
}

double DefaultPlatform::MonotonicallyIncreasingTime() {
  if (time_function_for_testing_) return time_function_for_testing_();
  return DefaultTimeFunction();
}

double DefaultPlatform::CurrentClockTimeMillis() {
  return base::OS::TimeCurrentMillis();
}

TracingController* DefaultPlatform::GetTracingController() {
  return tracing_controller_.get();
}

void DefaultPlatform::SetTracingController(
    std::unique_ptr<v8::TracingController> tracing_controller) {
  DCHECK_NOT_NULL(tracing_controller.get());
  tracing_controller_ = std::move(tracing_controller);
}

int DefaultPlatform::NumberOfWorkerThreads() { return thread_pool_size_; }

Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
  return PrintStackTrace;
}

v8::PageAllocator* DefaultPlatform::GetPageAllocator() {
  return page_allocator_.get();
}

void DefaultPlatform::NotifyIsolateShutdown(Isolate* isolate) {
  base::MutexGuard guard(&lock_);
  auto it = foreground_task_runner_map_.find(isolate);
  if (it != foreground_task_runner_map_.end()) {
    it->second->Terminate();
    foreground_task_runner_map_.erase(it);
  }
}

}  // namespace platform
}  // namespace v8
