// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/script/v8c/cobalt_platform.h"

#include <memory>

#include "base/logging.h"
#include "cobalt/base/polymorphic_downcast.h"

namespace cobalt {
namespace script {
namespace v8c {

CobaltPlatform::CobaltV8TaskRunner::CobaltV8TaskRunner()
    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {}

void CobaltPlatform::CobaltV8TaskRunner::PostTask(
    std::unique_ptr<v8::Task> task) {
  PostDelayedTask(std::move(task), 0);
}

void CobaltPlatform::CobaltV8TaskRunner::PostDelayedTask(
    std::unique_ptr<v8::Task> task, double delay_in_seconds) {
  base::AutoLock auto_lock(lock_);
  if (task_runner_) {
    task_runner_->PostDelayedTask(
        FROM_HERE,
        base::Bind(&CobaltPlatform::CobaltV8TaskRunner::RunV8Task,
                   weak_ptr_factory_.GetWeakPtr(), base::Passed(&task)),
        base::TimeDelta::FromSecondsD(delay_in_seconds));
  } else {
    tasks_before_registration_.push_back(
        std::unique_ptr<TaskBeforeRegistration>(
            new TaskBeforeRegistration(delay_in_seconds, std::move(task))));
  }
}

// Since we put these v8 tasks directly on the message loop, all the tasks are
// "NonNestable".
void CobaltPlatform::CobaltV8TaskRunner::PostNonNestableTask(
    std::unique_ptr<v8::Task> task) {
  return PostTask(std::move(task));
}
void CobaltPlatform::CobaltV8TaskRunner::PostNonNestableDelayedTask(
    std::unique_ptr<v8::Task> task, double delay_in_seconds) {
  return PostDelayedTask(std::move(task), 0);
}

void CobaltPlatform::CobaltV8TaskRunner::SetTaskRunner(
    base::SingleThreadTaskRunner* task_runner) {
  base::AutoLock auto_lock(lock_);
  task_runner_ = task_runner;
  DCHECK(task_runner);
  for (unsigned int i = 0; i < tasks_before_registration_.size(); ++i) {
    std::unique_ptr<v8::Task> scoped_task =
        std::move(tasks_before_registration_[i]->task);
    base::TimeDelta delay = std::max(
        tasks_before_registration_[i]->target_time - base::TimeTicks::Now(),
        base::TimeDelta::FromSeconds(0));
    task_runner_->PostDelayedTask(
        FROM_HERE,
        base::Bind(&CobaltPlatform::CobaltV8TaskRunner::RunV8Task,
                   weak_ptr_factory_.GetWeakPtr(), base::Passed(&scoped_task)),
        delay);
  }
  tasks_before_registration_.clear();
}

void CobaltPlatform::CobaltV8TaskRunner::RunV8Task(
    std::unique_ptr<v8::Task> task) {
  task->Run();
}

std::shared_ptr<v8::TaskRunner> CobaltPlatform::GetForegroundTaskRunner(
    v8::Isolate* isolate) {
  base::AutoLock auto_lock(lock_);
  std::shared_ptr<CobaltPlatform::CobaltV8TaskRunner> task_runner;
  if (v8_task_runner_map_.find(isolate) == v8_task_runner_map_.end()) {
    task_runner = std::make_shared<CobaltPlatform::CobaltV8TaskRunner>();
    v8_task_runner_map_.emplace(isolate, task_runner);
  } else {
    task_runner = v8_task_runner_map_[isolate];
  }
  DCHECK(task_runner);
  return task_runner;
}

void CobaltPlatform::RegisterIsolateOnThread(v8::Isolate* isolate,
                                             base::MessageLoop* message_loop) {
  DCHECK(message_loop);
  auto task_runner = GetForegroundTaskRunner(isolate);
  CobaltPlatform::CobaltV8TaskRunner* cobalt_v8_task_runner =
      base::polymorphic_downcast<CobaltPlatform::CobaltV8TaskRunner*>(
          task_runner.get());
  cobalt_v8_task_runner->SetTaskRunner(message_loop->task_runner().get());
}

void CobaltPlatform::UnregisterIsolateOnThread(v8::Isolate* isolate) {
  base::AutoLock auto_lock(lock_);
  auto iter = v8_task_runner_map_.find(isolate);
  if (iter != v8_task_runner_map_.end()) {
    v8_task_runner_map_.erase(iter);
  } else {
    DLOG(WARNING) << "Isolate is not in the map and can not be unregistered.";
  }
}

}  // namespace v8c
}  // namespace script
}  // namespace cobalt
