// 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 std::unique_ptr<v8::Platform>(platform.release());
}

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
