// Copyright 2022 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/worker/dedicated_worker.h"

#include <memory>
#include <string>

#include "cobalt/browser/stack_size_constants.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/web/event_target.h"
#include "cobalt/web/message_port.h"
#include "cobalt/worker/worker.h"
#include "cobalt/worker/worker_options.h"
#include "url/gurl.h"

namespace cobalt {
namespace worker {

namespace {
const char kDedicatedWorkerName[] = "DedicatedWorker";
}  // namespace

DedicatedWorker::DedicatedWorker(script::EnvironmentSettings* settings,
                                 const std::string& scriptURL)
    : web::EventTarget(settings), script_url_(scriptURL) {
  Initialize();
}

DedicatedWorker::DedicatedWorker(script::EnvironmentSettings* settings,
                                 const std::string& scriptURL,
                                 const WorkerOptions& worker_options)
    : web::EventTarget(settings),
      script_url_(scriptURL),
      worker_options_(worker_options) {
  Initialize();
}

void DedicatedWorker::Initialize() {
  // Algorithm for the Worker constructor.
  //   https://html.spec.whatwg.org/commit-snapshots/465a6b672c703054de278b0f8133eb3ad33d93f4/#dom-worker

  // 1. The user agent may throw a "SecurityError" web::DOMException if the
  // request
  //    violates a policy decision (e.g. if the user agent is configured to
  //    not
  //    allow the page to start dedicated workers).
  // 2. Let outside settings be the current settings object.
  // 3. Parse the scriptURL argument relative to outside settings.
  Worker::Options options(kDedicatedWorkerName);
  const GURL& base_url = environment_settings()->base_url();
  options.url = base_url.Resolve(script_url_);

  LOG_IF(WARNING, !options.url.is_valid())
      << script_url_ << " cannot be resolved based on " << base_url << ".";

  // 4. If this fails, throw a "SyntaxError" web::DOMException.
  // 5. Let worker URL be the resulting URL record.
  options.web_options.stack_size = cobalt::browser::kWorkerStackSize;
  options.web_options.network_module =
      environment_settings()->context()->network_module();
  // 6. Let worker be a new Worker object.
  // 7. Let outside port be a new MessagePort in outside settings's Realm.
  // 8. Associate the outside port with worker.
  outside_port_ = new web::MessagePort(this);
  // 9. Run this step in parallel:
  //    1. Run a worker given worker, worker URL, outside settings, outside
  //    port, and options.
  options.outside_settings = environment_settings();
  options.outside_port = outside_port_.get();
  options.options = worker_options_;
  options.web_options.service_worker_jobs =
      options.outside_settings->context()->service_worker_jobs();

  worker_.reset(new Worker(options));
  // 10. Return worker.
}

DedicatedWorker::~DedicatedWorker() { Terminate(); }

void DedicatedWorker::Terminate() {
  if (worker_) {
    worker_->Terminate();
  }
}

// void postMessage(any message, object transfer);
// -> void PostMessage(const script::ValueHandleHolder& message,
//                     script::Sequence<script::ValueHandle*> transfer) {}
void DedicatedWorker::PostMessage(const std::string& message) {
  DCHECK(worker_);
  worker_->PostMessage(message);
}


}  // namespace worker
}  // namespace cobalt
