/*
 * 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

using namespace HTMLNames;

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
