/*
 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/script/html_parser_script_runner.h"

#include <inttypes.h>
#include <memory>
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/document_parser_timing.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/parser/html_input_stream.h"
#include "third_party/blink/renderer/core/html/parser/nesting_level_incrementer.h"
#include "third_party/blink/renderer/core/script/html_parser_script_runner_host.h"
#include "third_party/blink/renderer/core/script/ignore_destructive_write_count_incrementer.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"

namespace blink {

namespace {

// TODO(bmcquade): move this to a shared location if we find ourselves wanting
// to trace similar data elsewhere in the codebase.
std::unique_ptr<TracedValue> GetTraceArgsForScriptElement(
    Document& document,
    const TextPosition& text_position,
    const KURL& url) {
  std::unique_ptr<TracedValue> value = TracedValue::Create();
  if (!url.IsNull())
    value->SetString("url", url.GetString());
  if (document.GetFrame()) {
    value->SetString(
        "frame",
        String::Format("0x%" PRIx64,
                       static_cast<uint64_t>(
                           reinterpret_cast<intptr_t>(document.GetFrame()))));
  }
  if (text_position.line_.ZeroBasedInt() > 0 ||
      text_position.column_.ZeroBasedInt() > 0) {
    value->SetInteger("lineNumber", text_position.line_.OneBasedInt());
    value->SetInteger("columnNumber", text_position.column_.OneBasedInt());
  }
  return value;
}

std::unique_ptr<TracedValue> GetTraceArgsForScriptElement(
    const PendingScript* pending_script) {
  DCHECK(pending_script);
  return GetTraceArgsForScriptElement(
      pending_script->GetElement()->GetDocument(),
      pending_script->StartingPosition(), pending_script->UrlForTracing());
}

void DoExecuteScript(PendingScript* pending_script, const KURL& document_url) {
  TRACE_EVENT_WITH_FLOW1("blink", "HTMLParserScriptRunner ExecuteScript",
                         pending_script->GetElement(), TRACE_EVENT_FLAG_FLOW_IN,
                         "data", GetTraceArgsForScriptElement(pending_script));
  pending_script->ExecuteScriptBlock(document_url);
}

void TraceParserBlockingScript(const PendingScript* pending_script,
                               bool waiting_for_resources) {
  // The HTML parser must yield before executing script in the following
  // cases:
  // * the script's execution is blocked on the completed load of the script
  //   resource
  //   (https://html.spec.whatwg.org/multipage/scripting.html#pending-parsing-blocking-script)
  // * the script's execution is blocked on the load of a style sheet or other
  //   resources that are blocking scripts
  //   (https://html.spec.whatwg.org/multipage/semantics.html#a-style-sheet-that-is-blocking-scripts)
  //
  // Both of these cases can introduce significant latency when loading a
  // web page, especially for users on slow connections, since the HTML parser
  // must yield until the blocking resources finish loading.
  //
  // We trace these parser yields here using flow events, so we can track
  // both when these yields occur, as well as how long the parser had
  // to yield. The connecting flow events are traced once the parser becomes
  // unblocked when the script actually executes, in doExecuteScript.
  ScriptElementBase* element = pending_script->GetElement();
  if (!element)
    return;
  if (!pending_script->IsReady()) {
    if (waiting_for_resources) {
      TRACE_EVENT_WITH_FLOW1("blink",
                             "YieldParserForScriptLoadAndBlockingResources",
                             element, TRACE_EVENT_FLAG_FLOW_OUT, "data",
                             GetTraceArgsForScriptElement(pending_script));
    } else {
      TRACE_EVENT_WITH_FLOW1("blink", "YieldParserForScriptLoad", element,
                             TRACE_EVENT_FLAG_FLOW_OUT, "data",
                             GetTraceArgsForScriptElement(pending_script));
    }
  } else if (waiting_for_resources) {
    TRACE_EVENT_WITH_FLOW1("blink", "YieldParserForScriptBlockingResources",
                           element, TRACE_EVENT_FLAG_FLOW_OUT, "data",
                           GetTraceArgsForScriptElement(pending_script));
  }
}

static KURL DocumentURLForScriptExecution(Document* document) {
  if (!document)
    return KURL();

  if (!document->GetFrame()) {
    if (document->ImportsController())
      return document->Url();
    return KURL();
  }

  // Use the URL of the currently active document for this frame.
  return document->GetFrame()->GetDocument()->Url();
}

}  // namespace

HTMLParserScriptRunner::HTMLParserScriptRunner(
    HTMLParserReentryPermit* reentry_permit,
    Document* document,
    HTMLParserScriptRunnerHost* host)
    : reentry_permit_(reentry_permit), document_(document), host_(host) {
  DCHECK(host_);
}

HTMLParserScriptRunner::~HTMLParserScriptRunner() {}

void HTMLParserScriptRunner::Detach() {
  if (!document_)
    return;

  if (parser_blocking_script_)
    parser_blocking_script_->Dispose();
  parser_blocking_script_ = nullptr;

  while (!scripts_to_execute_after_parsing_.IsEmpty()) {
    PendingScript* pending_script =
        scripts_to_execute_after_parsing_.TakeFirst();
    pending_script->Dispose();
  }
  document_ = nullptr;
  // m_reentryPermit is not cleared here, because the script runner
  // may continue to run pending scripts after the parser has
  // detached.
}

bool HTMLParserScriptRunner::IsParserBlockingScriptReady() {
  DCHECK(ParserBlockingScript());
  if (!document_->IsScriptExecutionReady())
    return false;
  return ParserBlockingScript()->IsReady();
}

// Corresponds to some steps of the "Otherwise" Clause of 'An end tag whose
// tag name is "script"'
// <specdef href="https://html.spec.whatwg.org/#scriptEndTag">
void HTMLParserScriptRunner::
    ExecutePendingParserBlockingScriptAndDispatchEvent() {
  // Stop watching loads before executeScript to prevent recursion if the script
  // reloads itself.
  // TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the
  // if block.
  // TODO(kouhei, hiroshige): Consider merging this w/ the code clearing
  // |parser_blocking_script_| below.
  PendingScript* pending_script = parser_blocking_script_;
  pending_script->StopWatchingForLoad();

  if (!IsExecutingScript()) {
    // TODO(kouhei, hiroshige): Investigate why we need checkpoint here.
    Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
    // The parser cannot be unblocked as a microtask requested another
    // resource
    if (!document_->IsScriptExecutionReady())
      return;
  }

  // <spec step="B.1">Let the script be the pending parsing-blocking script.
  // There is no longer a pending parsing-blocking script.</spec>
  parser_blocking_script_ = nullptr;

  {
    // <spec step="B.7">Increment the parser's script nesting level by one (it
    // should be zero before this step, so this sets it to one).</spec>
    HTMLParserReentryPermit::ScriptNestingLevelIncrementer
        nesting_level_incrementer =
            reentry_permit_->IncrementScriptNestingLevel();

    // TODO(hiroshige): Remove IgnoreDestructiveWriteCountIncrementer here,
    // according to the spec. After https://crbug.com/721914 is resolved,
    // |document_| is equal to the element's context document used in
    // PendingScript::ExecuteScriptBlockInternal(), and thus this can be removed
    // more easily.
    IgnoreDestructiveWriteCountIncrementer
        ignore_destructive_write_count_incrementer(document_);

    // <spec step="B.8">Execute the script.</spec>
    DCHECK(IsExecutingScript());
    DoExecuteScript(pending_script, DocumentURLForScriptExecution(document_));

    // <spec step="B.9">Decrement the parser's script nesting level by one. If
    // the parser's script nesting level is zero (which it always should be at
    // this point), then set the parser pause flag to false.</spec>
    //
    // This is implemented by ~ScriptNestingLevelIncrementer().
  }

  DCHECK(!IsExecutingScript());
}

// Should be correspond to
//
// <specdef
// href="https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block">
//
// but currently does more than specced, because historically this and
// ExecutePendingParserBlockingScriptAndDispatchEvent() was the same method.
// TODO(hiroshige): Make this spec-conformant.
void HTMLParserScriptRunner::ExecutePendingDeferredScriptAndDispatchEvent(
    PendingScript* pending_script) {
  // Stop watching loads before executeScript to prevent recursion if the script
  // reloads itself.
  // TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the
  // if block.
  pending_script->StopWatchingForLoad();

  if (!IsExecutingScript()) {
    // TODO(kouhei, hiroshige): Investigate why we need checkpoint here.
    Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
  }

  {
    // The following code corresponds to:
    //
    // <spec href="https://html.spec.whatwg.org/#scriptEndTag"
    // step="B.7">Increment the parser's script nesting level by one (it should
    // be zero before this step, so this sets it to one).</spec>
    //
    // but this shouldn't be executed here according to the
    // #execute-the-script-block spec.
    HTMLParserReentryPermit::ScriptNestingLevelIncrementer
        nesting_level_incrementer =
            reentry_permit_->IncrementScriptNestingLevel();

    // <spec step="3">... increment the ignore-destructive-writes counter of the
    // script element's node document. ...</spec>
    //
    // TODO(hiroshige): This is duplicated (also done in ExecuteScriptBlock())).
    IgnoreDestructiveWriteCountIncrementer
        ignore_destructive_write_count_incrementer(document_);

    DCHECK(IsExecutingScript());
    DoExecuteScript(pending_script, DocumentURLForScriptExecution(document_));
  }

  DCHECK(!IsExecutingScript());
}

void HTMLParserScriptRunner::PendingScriptFinished(
    PendingScript* pending_script) {
  // Handle cancellations of parser-blocking script loads without
  // notifying the host (i.e., parser) if these were initiated by nested
  // document.write()s. The cancellation may have been triggered by
  // script execution to signal an abrupt stop (e.g., window.close().)
  //
  // The parser is unprepared to be told, and doesn't need to be.
  if (IsExecutingScript() && pending_script->WasCanceled()) {
    pending_script->Dispose();

    DCHECK_EQ(pending_script, ParserBlockingScript());
    parser_blocking_script_ = nullptr;

    return;
  }

  host_->NotifyScriptLoaded(pending_script);
}

// <specdef href="https://html.spec.whatwg.org/#scriptEndTag">
//
// Script handling lives outside the tree builder to keep each class simple.
void HTMLParserScriptRunner::ProcessScriptElement(
    Element* script_element,
    const TextPosition& script_start_position) {
  DCHECK(script_element);

  // FIXME: If scripting is disabled, always just return.

  bool had_preload_scanner = host_->HasPreloadScanner();

  // <spec>An end tag whose tag name is "script" ...</spec>
  //
  // Try to execute the script given to us.
  ProcessScriptElementInternal(script_element, script_start_position);

  // <spec>... At this stage, if there is a pending parsing-blocking script,
  // then:</spec>
  if (HasParserBlockingScript()) {
    // <spec step="A">If the script nesting level is not zero: ...</spec>
    if (IsExecutingScript()) {
      // <spec step="A">If the script nesting level is not zero:
      //
      // Set the parser pause flag to true, and abort the processing of any
      // nested invocations of the tokenizer, yielding control back to the
      // caller. (Tokenization will resume when the caller returns to the
      // "outer" tree construction stage.)</spec>
      //
      // <spec>... set the parser pause flag to ...</spec>

      // Unwind to the outermost HTMLParserScriptRunner::processScriptElement
      // before continuing parsing.
      return;
    }

    // - "Otherwise":

    TraceParserBlockingScript(ParserBlockingScript(),
                              !document_->IsScriptExecutionReady());
    parser_blocking_script_->MarkParserBlockingLoadStartTime();

    // If preload scanner got created, it is missing the source after the
    // current insertion point. Append it and scan.
    if (!had_preload_scanner && host_->HasPreloadScanner())
      host_->AppendCurrentInputStreamToPreloadScannerAndScan();

    ExecuteParsingBlockingScripts();
  }
}

bool HTMLParserScriptRunner::HasParserBlockingScript() const {
  return ParserBlockingScript();
}

// <specdef href="https://html.spec.whatwg.org/#scriptEndTag">
//
// <spec>An end tag whose tag name is "script" ...</spec>
void HTMLParserScriptRunner::ExecuteParsingBlockingScripts() {
  // <spec step="B.3">If the parser's Document has a style sheet that is
  // blocking scripts or the script's "ready to be parser-executed" flag is not
  // set: spin the event loop until the parser's Document has no style sheet
  // that is blocking scripts and the script's "ready to be parser-executed"
  // flag is set.</spec>
  //
  // These conditions correspond to isParserBlockingScriptReady() and
  // if it is false, executeParsingBlockingScripts() will be called later
  // when isParserBlockingScriptReady() becomes true:
  // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or
  // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad().
  while (HasParserBlockingScript() && IsParserBlockingScriptReady()) {
    DCHECK(document_);
    DCHECK(!IsExecutingScript());
    DCHECK(document_->IsScriptExecutionReady());

    // <spec step="B.6">Let the insertion point be just before the next input
    // character.</spec>
    InsertionPointRecord insertion_point_record(host_->InputStream());

    // 1., 7.--9.
    ExecutePendingParserBlockingScriptAndDispatchEvent();

    // <spec step="B.10">Let the insertion point be undefined again.</spec>
    //
    // Implemented as ~InsertionPointRecord().

    // <spec step="B.11">If there is once again a pending parsing-blocking
    // script, then repeat these steps from step 1.</spec>
  }
}

void HTMLParserScriptRunner::ExecuteScriptsWaitingForLoad(
    PendingScript* pending_script) {
  TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad");
  DCHECK(!IsExecutingScript());
  DCHECK(HasParserBlockingScript());
  DCHECK_EQ(pending_script, ParserBlockingScript());
  DCHECK(ParserBlockingScript()->IsReady());
  ExecuteParsingBlockingScripts();
}

void HTMLParserScriptRunner::ExecuteScriptsWaitingForResources() {
  TRACE_EVENT0("blink",
               "HTMLParserScriptRunner::executeScriptsWaitingForResources");
  DCHECK(document_);
  DCHECK(!IsExecutingScript());
  DCHECK(document_->IsScriptExecutionReady());
  ExecuteParsingBlockingScripts();
}

// <specdef href="https://html.spec.whatwg.org/#stop-parsing">
//
// <spec step="3">If the list of scripts that will execute when the document has
// finished parsing is not empty, run these substeps:</spec>
bool HTMLParserScriptRunner::ExecuteScriptsWaitingForParsing() {
  TRACE_EVENT0("blink",
               "HTMLParserScriptRunner::executeScriptsWaitingForParsing");

  while (!scripts_to_execute_after_parsing_.IsEmpty()) {
    DCHECK(!IsExecutingScript());
    DCHECK(!HasParserBlockingScript());
    DCHECK(scripts_to_execute_after_parsing_.front()->IsExternalOrModule());

    // <spec step="3.1">Spin the event loop until the first script in the list
    // of scripts that will execute when the document has finished parsing has
    // its "ready to be parser-executed" flag set and the parser's Document has
    // no style sheet that is blocking scripts.</spec>
    //
    // TODO(hiroshige): Is the latter part checked anywhere?
    if (!scripts_to_execute_after_parsing_.front()->IsReady()) {
      scripts_to_execute_after_parsing_.front()->WatchForLoad(this);
      TraceParserBlockingScript(scripts_to_execute_after_parsing_.front().Get(),
                                !document_->IsScriptExecutionReady());
      scripts_to_execute_after_parsing_.front()
          ->MarkParserBlockingLoadStartTime();
      return false;
    }

    // <spec step="3.3">Remove the first script element from the list of scripts
    // that will execute when the document has finished parsing (i.e. shift out
    // the first entry in the list).</spec>
    PendingScript* first = scripts_to_execute_after_parsing_.TakeFirst();

    // <spec step="3.2">Execute the first script in the list of scripts that
    // will execute when the document has finished parsing.</spec>
    ExecutePendingDeferredScriptAndDispatchEvent(first);

    // FIXME: What is this m_document check for?
    if (!document_)
      return false;

    // <spec step="3.4">If the list of scripts that will execute when the
    // document has finished parsing is still not empty, repeat these substeps
    // again from substep 1.</spec>
  }
  return true;
}

void HTMLParserScriptRunner::RequestParsingBlockingScript(
    ScriptLoader* script_loader) {
  // <spec href="https://html.spec.whatwg.org/#prepare-a-script" step="26.B">...
  // The element is the pending parsing-blocking script of the Document of the
  // parser that created the element. (There can only be one such script per
  // Document at a time.) ...</spec>
  CHECK(!ParserBlockingScript());
  parser_blocking_script_ =
      script_loader->TakePendingScript(ScriptSchedulingType::kParserBlocking);
  if (!ParserBlockingScript())
    return;

  DCHECK(ParserBlockingScript()->IsExternal());

  // We only care about a load callback if resource is not already in the cache.
  // Callers will attempt to run the m_parserBlockingScript if possible before
  // returning control to the parser.
  if (!ParserBlockingScript()->IsReady()) {
    parser_blocking_script_->StartStreamingIfPossible(base::OnceClosure());
    parser_blocking_script_->WatchForLoad(this);
  }
}

void HTMLParserScriptRunner::RequestDeferredScript(
    ScriptLoader* script_loader) {
  PendingScript* pending_script =
      script_loader->TakePendingScript(ScriptSchedulingType::kDefer);
  if (!pending_script)
    return;

  if (!pending_script->IsReady()) {
    pending_script->StartStreamingIfPossible(base::OnceClosure());
  }

  DCHECK(pending_script->IsExternalOrModule());

  // <spec href="https://html.spec.whatwg.org/#prepare-a-script" step="26.A">...
  // Add the element to the end of the list of scripts that will execute when
  // the document has finished parsing associated with the Document of the
  // parser that created the element. ...</spec>
  scripts_to_execute_after_parsing_.push_back(pending_script);
}

// The initial steps for 'An end tag whose tag name is "script"'
// <specdef href="https://html.spec.whatwg.org/#scriptEndTag">
// <specdef label="prepare-a-script"
// href="https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script">
void HTMLParserScriptRunner::ProcessScriptElementInternal(
    Element* script,
    const TextPosition& script_start_position) {
  DCHECK(document_);
  DCHECK(!HasParserBlockingScript());
  {
    ScriptLoader* script_loader = ScriptLoaderFromElement(script);

    // FIXME: Align trace event name and function name.
    TRACE_EVENT1("blink", "HTMLParserScriptRunner::execute", "data",
                 GetTraceArgsForScriptElement(*document_, script_start_position,
                                              NullURL()));
    DCHECK(script_loader->IsParserInserted());

    if (!IsExecutingScript())
      Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());

    // <spec>... Let the old insertion point have the same value as the current
    // insertion point. Let the insertion point be just before the next input
    // character. ...</spec>
    InsertionPointRecord insertion_point_record(host_->InputStream());

    // <spec>... Increment the parser's script nesting level by one. ...</spec>
    HTMLParserReentryPermit::ScriptNestingLevelIncrementer
        nesting_level_incrementer =
            reentry_permit_->IncrementScriptNestingLevel();

    // <spec>... Prepare the script. This might cause some script to execute,
    // which might cause new characters to be inserted into the tokenizer, and
    // might cause the tokenizer to output more tokens, resulting in a reentrant
    // invocation of the parser. ...</spec>
    script_loader->PrepareScript(script_start_position);

    if (!script_loader->WillBeParserExecuted())
      return;

    if (script_loader->WillExecuteWhenDocumentFinishedParsing()) {
      RequestDeferredScript(script_loader);
    } else if (script_loader->ReadyToBeParserExecuted()) {
      // <spec label="prepare-a-script" step="26.E">... it's an HTML parser
      // whose script nesting level is not greater than one, ...</spec>
      if (reentry_permit_->ScriptNestingLevel() == 1u) {
        // <spec label="prepare-a-script" step="26.E">... The element is the
        // pending parsing-blocking script of the Document of the parser that
        // created the element. (There can only be one such script per Document
        // at a time.) ...</spec>
        CHECK(!parser_blocking_script_);
        parser_blocking_script_ = script_loader->TakePendingScript(
            ScriptSchedulingType::kParserBlockingInline);
      } else {
        // <spec label="prepare-a-script" step="26.F">Otherwise
        //
        // Immediately execute the script block, even if other scripts are
        // already executing.</spec>
        //
        // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript().
        DCHECK_GT(reentry_permit_->ScriptNestingLevel(), 1u);
        if (parser_blocking_script_)
          parser_blocking_script_->Dispose();
        parser_blocking_script_ = nullptr;
        DoExecuteScript(
            script_loader->TakePendingScript(ScriptSchedulingType::kImmediate),
            DocumentURLForScriptExecution(document_));
      }
    } else {
      // [PS] Step 25.B.
      RequestParsingBlockingScript(script_loader);
    }

    // <spec>... Decrement the parser's script nesting level by one. If the
    // parser's script nesting level is zero, then set the parser pause flag to
    // false. ...</spec>
    //
    // Implemented by ~ScriptNestingLevelIncrementer().

    // <spec>... Let the insertion point have the value of the old insertion
    // point. ...</spec>
    //
    // Implemented by ~InsertionPointRecord().
  }
}

void HTMLParserScriptRunner::Trace(blink::Visitor* visitor) {
  visitor->Trace(document_);
  visitor->Trace(host_);
  visitor->Trace(parser_blocking_script_);
  visitor->Trace(scripts_to_execute_after_parsing_);
  PendingScriptClient::Trace(visitor);
}

}  // namespace blink
