// Copyright 2017 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 "third_party/blink/renderer/core/script/module_script.h"

#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/script/script_module_resolver.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "v8/include/v8.h"

namespace blink {

// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
ModuleScript* ModuleScript::Create(const MovableString& original_source_text,
                                   Modulator* modulator,
                                   const KURL& source_url,
                                   const KURL& base_url,
                                   const ScriptFetchOptions& options,
                                   AccessControlStatus access_control_status,
                                   const TextPosition& start_position) {
  // <spec step="1">If scripting is disabled for settings's responsible browsing
  // context, then set source to the empty string.</spec>
  MovableString source_text;
  if (!modulator->IsScriptingDisabled())
    source_text = original_source_text;

  // <spec step="2">Let script be a new module script that this algorithm will
  // subsequently initialize.</spec>

  // <spec step="3">Set script's settings object to settings.</spec>
  //
  // Note: "script's settings object" will be |modulator|.

  // <spec step="7">Let result be ParseModule(source, settings's Realm,
  // script).</spec>
  ScriptState* script_state = modulator->GetScriptState();
  ScriptState::Scope scope(script_state);
  v8::Isolate* isolate = script_state->GetIsolate();
  ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
                                 "ModuleScript", "Create");

  ScriptModule result = ScriptModule::Compile(
      isolate, source_text.ToString(), source_url, base_url, options,
      access_control_status, start_position, exception_state);

  // CreateInternal processes Steps 4 and 8-10.
  //
  // [nospec] We initialize the other ModuleScript members anyway by running
  // Steps 8-13 before Step 6. In a case that compile failed, we will
  // immediately turn the script into errored state. Thus the members will not
  // be used for the speced algorithms, but may be used from inspector.
  ModuleScript* script =
      CreateInternal(source_text, modulator, result, source_url, base_url,
                     options, start_position);

  // <spec step="8">If result is a list of errors, then:</spec>
  if (exception_state.HadException()) {
    DCHECK(result.IsNull());

    // <spec step="8.1">Set script's parse error to result[0].</spec>
    v8::Local<v8::Value> error = exception_state.GetException();
    exception_state.ClearException();
    script->SetParseErrorAndClearRecord(ScriptValue(script_state, error));

    // <spec step="8.2">Return script.</spec>
    return script;
  }

  // <spec step="9">For each string requested of
  // result.[[RequestedModules]]:</spec>
  for (const auto& requested :
       modulator->ModuleRequestsFromScriptModule(result)) {
    // <spec step="9.1">Let url be the result of resolving a module specifier
    // given script and requested.</spec>
    //
    // <spec step="9.2">If url is failure, then:</spec>
    String failure_reason;
    if (script->ResolveModuleSpecifier(requested.specifier, &failure_reason)
            .IsValid())
      continue;

    // <spec step="9.2.1">Let error be a new TypeError exception.</spec>
    String error_message = "Failed to resolve module specifier \"" +
                           requested.specifier + "\". " + failure_reason;
    v8::Local<v8::Value> error =
        V8ThrowException::CreateTypeError(isolate, error_message);

    // <spec step="9.2.2">Set script's parse error to error.</spec>
    script->SetParseErrorAndClearRecord(ScriptValue(script_state, error));

    // <spec step="9.2.3">Return script.</spec>
    return script;
  }

  // <spec step="11">Return script.</spec>
  return script;
}

ModuleScript* ModuleScript::CreateForTest(Modulator* modulator,
                                          ScriptModule record,
                                          const KURL& base_url,
                                          const ScriptFetchOptions& options) {
  MovableString dummy_source_text(String("").ReleaseImpl());
  KURL dummy_source_url;
  return CreateInternal(dummy_source_text, modulator, record, dummy_source_url,
                        base_url, options, TextPosition::MinimumPosition());
}

// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
ModuleScript* ModuleScript::CreateInternal(const MovableString& source_text,
                                           Modulator* modulator,
                                           ScriptModule result,
                                           const KURL& source_url,
                                           const KURL& base_url,
                                           const ScriptFetchOptions& options,
                                           const TextPosition& start_position) {
  // <spec step="6">Set script's parse error and error to rethrow to
  // null.</spec>
  //
  // <spec step="10">Set script's record to result.</spec>
  //
  // <spec step="4">Set script's base URL to baseURL.</spec>
  //
  // <spec step="5">Set script's fetch options to options.</spec>
  //
  // [nospec] |source_text| is saved for CSP checks.
  ModuleScript* module_script =
      new ModuleScript(modulator, result, source_url, base_url, options,
                       source_text, start_position);

  // Step 7, a part of ParseModule(): Passing script as the last parameter
  // here ensures result.[[HostDefined]] will be script.
  modulator->GetScriptModuleResolver()->RegisterModuleScript(module_script);

  return module_script;
}

ModuleScript::ModuleScript(Modulator* settings_object,
                           ScriptModule record,
                           const KURL& source_url,
                           const KURL& base_url,
                           const ScriptFetchOptions& fetch_options,
                           const MovableString& source_text,
                           const TextPosition& start_position)
    : Script(fetch_options, base_url),
      settings_object_(settings_object),
      source_text_(source_text),
      start_position_(start_position),
      source_url_(source_url) {
  if (record.IsNull()) {
    // We allow empty records for module infra tests which never touch records.
    // This should never happen outside unit tests.
    return;
  }

  DCHECK(settings_object);
  v8::Isolate* isolate = settings_object_->GetScriptState()->GetIsolate();
  v8::HandleScope scope(isolate);
  record_.Set(isolate, record.NewLocal(isolate));
}

ScriptModule ModuleScript::Record() const {
  if (record_.IsEmpty())
    return ScriptModule();

  v8::Isolate* isolate = settings_object_->GetScriptState()->GetIsolate();
  v8::HandleScope scope(isolate);
  return ScriptModule(isolate, record_.NewLocal(isolate), source_url_);
}

bool ModuleScript::HasEmptyRecord() const {
  return record_.IsEmpty();
}

void ModuleScript::SetParseErrorAndClearRecord(ScriptValue error) {
  DCHECK(!error.IsEmpty());

  record_.Clear();
  ScriptState::Scope scope(error.GetScriptState());
  parse_error_.Set(error.GetIsolate(), error.V8Value());
}

ScriptValue ModuleScript::CreateParseError() const {
  ScriptState* script_state = settings_object_->GetScriptState();
  v8::Isolate* isolate = script_state->GetIsolate();
  ScriptState::Scope scope(script_state);
  ScriptValue error(script_state, parse_error_.NewLocal(isolate));
  DCHECK(!error.IsEmpty());
  return error;
}

void ModuleScript::SetErrorToRethrow(ScriptValue error) {
  ScriptState::Scope scope(error.GetScriptState());
  error_to_rethrow_.Set(error.GetIsolate(), error.V8Value());
}

ScriptValue ModuleScript::CreateErrorToRethrow() const {
  ScriptState* script_state = settings_object_->GetScriptState();
  v8::Isolate* isolate = script_state->GetIsolate();
  ScriptState::Scope scope(script_state);
  ScriptValue error(script_state, error_to_rethrow_.NewLocal(isolate));
  DCHECK(!error.IsEmpty());
  return error;
}

KURL ModuleScript::ResolveModuleSpecifier(const String& module_request,
                                          String* failure_reason) {
  auto found = specifier_to_url_cache_.find(module_request);
  if (found != specifier_to_url_cache_.end())
    return found->value;

  KURL url = settings_object_->ResolveModuleSpecifier(module_request, BaseURL(),
                                                      failure_reason);
  // Cache the result only on success, so that failure_reason is set for
  // subsequent calls too.
  if (url.IsValid())
    specifier_to_url_cache_.insert(module_request, url);
  return url;
}

void ModuleScript::Trace(blink::Visitor* visitor) {
  visitor->Trace(settings_object_);
  visitor->Trace(record_.UnsafeCast<v8::Value>());
  visitor->Trace(parse_error_);
  visitor->Trace(error_to_rethrow_);
  Script::Trace(visitor);
}

void ModuleScript::RunScript(LocalFrame* frame, const SecurityOrigin*) const {
  DVLOG(1) << *this << "::RunScript()";
  settings_object_->ExecuteModule(this,
                                  Modulator::CaptureEvalErrorFlag::kReport);
}

String ModuleScript::InlineSourceTextForCSP() const {
  return source_text_.ToString();
}

std::ostream& operator<<(std::ostream& stream,
                         const ModuleScript& module_script) {
  stream << "ModuleScript[" << &module_script;
  if (module_script.HasEmptyRecord())
    stream << ", empty-record";

  if (module_script.HasErrorToRethrow())
    stream << ", error-to-rethrow";

  if (module_script.HasParseError())
    stream << ", parse-error";

  return stream << "]";
}

}  // namespace blink
