// Copyright 2016 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/bindings/core/v8/script_custom_element_definition.h"

#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_element.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/html/custom/custom_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "v8/include/v8.h"

namespace blink {

class CSSStyleSheet;

ScriptCustomElementDefinition* ScriptCustomElementDefinition::ForConstructor(
    ScriptState* script_state,
    CustomElementRegistry* registry,
    const v8::Local<v8::Value>& constructor) {
  V8PerContextData* per_context_data = script_state->PerContextData();
  // TODO(yukishiino): Remove this check when crbug.com/583429 is fixed.
  if (UNLIKELY(!per_context_data))
    return nullptr;
  auto private_id = per_context_data->GetPrivateCustomElementDefinitionId();
  v8::Local<v8::Value> id_value;
  if (!constructor.As<v8::Object>()
           ->GetPrivate(script_state->GetContext(), private_id)
           .ToLocal(&id_value))
    return nullptr;
  if (!id_value->IsUint32())
    return nullptr;
  uint32_t id = id_value.As<v8::Uint32>()->Value();

  // This downcast is safe because only ScriptCustomElementDefinitions
  // have an ID associated with them. This relies on three things:
  //
  // 1. Only ScriptCustomElementDefinition::Create sets the private
  //    property on a constructor.
  //
  // 2. CustomElementRegistry adds ScriptCustomElementDefinitions
  //    assigned an ID to the list of definitions without fail.
  //
  // 3. The relationship between the CustomElementRegistry and its
  //    private property is never mixed up; this is guaranteed by the
  //    bindings system because the registry is associated with its
  //    context.
  //
  // At a meta-level, this downcast is safe because there is
  // currently only one implementation of CustomElementDefinition in
  // product code and that is ScriptCustomElementDefinition. But
  // that may change in the future.
  CustomElementDefinition* definition = registry->DefinitionForId(id);
  CHECK(definition);
  return static_cast<ScriptCustomElementDefinition*>(definition);
}

ScriptCustomElementDefinition* ScriptCustomElementDefinition::Create(
    ScriptState* script_state,
    CustomElementRegistry* registry,
    const CustomElementDescriptor& descriptor,
    CustomElementDefinition::Id id,
    const v8::Local<v8::Object>& constructor,
    const v8::Local<v8::Function>& connected_callback,
    const v8::Local<v8::Function>& disconnected_callback,
    const v8::Local<v8::Function>& adopted_callback,
    const v8::Local<v8::Function>& attribute_changed_callback,
    HashSet<AtomicString>&& observed_attributes,
    CSSStyleSheet* default_style_sheet) {
  ScriptCustomElementDefinition* definition = new ScriptCustomElementDefinition(
      script_state, descriptor, constructor, connected_callback,
      disconnected_callback, adopted_callback, attribute_changed_callback,
      std::move(observed_attributes), default_style_sheet);

  // Tag the JavaScript constructor object with its ID.
  v8::Local<v8::Value> id_value =
      v8::Integer::NewFromUnsigned(script_state->GetIsolate(), id);
  auto private_id =
      script_state->PerContextData()->GetPrivateCustomElementDefinitionId();
  CHECK(
      constructor->SetPrivate(script_state->GetContext(), private_id, id_value)
          .ToChecked());

  return definition;
}

ScriptCustomElementDefinition::ScriptCustomElementDefinition(
    ScriptState* script_state,
    const CustomElementDescriptor& descriptor,
    const v8::Local<v8::Object>& constructor,
    const v8::Local<v8::Function>& connected_callback,
    const v8::Local<v8::Function>& disconnected_callback,
    const v8::Local<v8::Function>& adopted_callback,
    const v8::Local<v8::Function>& attribute_changed_callback,
    HashSet<AtomicString>&& observed_attributes,
    CSSStyleSheet* default_style_sheet)
    : CustomElementDefinition(descriptor,
                              default_style_sheet,
                              std::move(observed_attributes)),
      script_state_(script_state),
      constructor_(script_state->GetIsolate(), constructor) {
  v8::Isolate* isolate = script_state->GetIsolate();
  if (!connected_callback.IsEmpty())
    connected_callback_.Set(isolate, connected_callback);
  if (!disconnected_callback.IsEmpty())
    disconnected_callback_.Set(isolate, disconnected_callback);
  if (!adopted_callback.IsEmpty())
    adopted_callback_.Set(isolate, adopted_callback);
  if (!attribute_changed_callback.IsEmpty())
    attribute_changed_callback_.Set(isolate, attribute_changed_callback);
}

void ScriptCustomElementDefinition::Trace(Visitor* visitor) {
  visitor->Trace(constructor_.Cast<v8::Value>());
  visitor->Trace(connected_callback_.Cast<v8::Value>());
  visitor->Trace(disconnected_callback_.Cast<v8::Value>());
  visitor->Trace(adopted_callback_.Cast<v8::Value>());
  visitor->Trace(attribute_changed_callback_.Cast<v8::Value>());
  CustomElementDefinition::Trace(visitor);
}

HTMLElement* ScriptCustomElementDefinition::HandleCreateElementSyncException(
    Document& document,
    const QualifiedName& tag_name,
    v8::Isolate* isolate,
    ExceptionState& exception_state) {
  DCHECK(exception_state.HadException());
  // 6.1."If any of these subsubsteps threw an exception".1
  // Report the exception.
  V8ScriptRunner::ReportException(isolate, exception_state.GetException());
  exception_state.ClearException();
  // ... .2 Return HTMLUnknownElement.
  return CustomElement::CreateFailedElement(document, tag_name);
}

HTMLElement* ScriptCustomElementDefinition::CreateAutonomousCustomElementSync(
    Document& document,
    const QualifiedName& tag_name) {
  if (!script_state_->ContextIsValid())
    return CustomElement::CreateFailedElement(document, tag_name);
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();

  ExceptionState exception_state(isolate, ExceptionState::kConstructionContext,
                                 "CustomElement");

  // Create an element with the synchronous custom elements flag set.
  // https://dom.spec.whatwg.org/#concept-create-element

  // TODO(dominicc): Implement step 5 which constructs customized
  // built-in elements.

  Element* element = nullptr;
  {
    v8::TryCatch try_catch(script_state_->GetIsolate());

    if (document.IsHTMLImport()) {
      // V8HTMLElement::constructorCustom() can only refer to
      // window.document() which is not the import document. Create
      // elements in import documents ahead of time so they end up in
      // the right document. This subtly violates recursive
      // construction semantics, but only in import documents.
      element = CreateElementForConstructor(document);
      DCHECK(!try_catch.HasCaught());

      ConstructionStackScope construction_stack_scope(this, element);
      element = CallConstructor();
    } else {
      element = CallConstructor();
    }

    if (try_catch.HasCaught()) {
      exception_state.RethrowV8Exception(try_catch.Exception());
      return HandleCreateElementSyncException(document, tag_name, isolate,
                                              exception_state);
    }
  }

  // 6.1.3. through 6.1.9.
  CheckConstructorResult(element, document, tag_name, exception_state);
  if (exception_state.HadException()) {
    return HandleCreateElementSyncException(document, tag_name, isolate,
                                            exception_state);
  }
  // 6.1.10. Set result’s namespace prefix to prefix.
  if (element->prefix() != tag_name.Prefix())
    element->SetTagNameForCreateElementNS(tag_name);
  DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kCustom);
  return ToHTMLElement(element);
}

// https://html.spec.whatwg.org/multipage/scripting.html#upgrades
bool ScriptCustomElementDefinition::RunConstructor(Element* element) {
  if (!script_state_->ContextIsValid())
    return false;
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();

  // Step 5 says to rethrow the exception; but there is no one to
  // catch it. The side effect is to report the error.
  v8::TryCatch try_catch(isolate);
  try_catch.SetVerbose(true);

  Element* result = CallConstructor();

  // To report exception thrown from callConstructor()
  if (try_catch.HasCaught())
    return false;

  // To report InvalidStateError Exception, when the constructor returns some
  // different object
  if (result != element) {
    const String& message =
        "custom element constructors must call super() first and must "
        "not return a different object";
    v8::Local<v8::Value> exception = V8ThrowDOMException::CreateOrEmpty(
        script_state_->GetIsolate(), DOMExceptionCode::kInvalidStateError,
        message);
    if (!exception.IsEmpty())
      V8ScriptRunner::ReportException(isolate, exception);
    return false;
  }

  return true;
}

Element* ScriptCustomElementDefinition::CallConstructor() {
  v8::Isolate* isolate = script_state_->GetIsolate();
  DCHECK(ScriptState::Current(isolate) == script_state_);
  ExecutionContext* execution_context =
      ExecutionContext::From(script_state_.get());
  v8::Local<v8::Value> result;
  if (!V8ScriptRunner::CallAsConstructor(isolate, Constructor(),
                                         execution_context, 0, nullptr)
           .ToLocal(&result)) {
    return nullptr;
  }
  return V8Element::ToImplWithTypeCheck(isolate, result);
}

v8::Local<v8::Object> ScriptCustomElementDefinition::Constructor() const {
  DCHECK(!constructor_.IsEmpty());
  return constructor_.NewLocal(script_state_->GetIsolate());
}

// CustomElementDefinition
ScriptValue ScriptCustomElementDefinition::GetConstructorForScript() {
  return ScriptValue(script_state_.get(), Constructor());
}

bool ScriptCustomElementDefinition::HasConnectedCallback() const {
  return !connected_callback_.IsEmpty();
}

bool ScriptCustomElementDefinition::HasDisconnectedCallback() const {
  return !disconnected_callback_.IsEmpty();
}

bool ScriptCustomElementDefinition::HasAdoptedCallback() const {
  return !adopted_callback_.IsEmpty();
}

void ScriptCustomElementDefinition::RunCallback(
    v8::Local<v8::Function> callback,
    Element* element,
    int argc,
    v8::Local<v8::Value> argv[]) {
  DCHECK(ScriptState::Current(script_state_->GetIsolate()) == script_state_);
  v8::Isolate* isolate = script_state_->GetIsolate();

  // Invoke custom element reactions
  // https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
  // If this throws any exception, then report the exception.
  v8::TryCatch try_catch(isolate);
  try_catch.SetVerbose(true);

  ExecutionContext* execution_context =
      ExecutionContext::From(script_state_.get());
  v8::Local<v8::Value> element_handle =
      ToV8(element, script_state_->GetContext()->Global(), isolate);
  V8ScriptRunner::CallFunction(callback, execution_context, element_handle,
                               argc, argv, isolate);
}

void ScriptCustomElementDefinition::RunConnectedCallback(Element* element) {
  if (!script_state_->ContextIsValid())
    return;
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();
  RunCallback(connected_callback_.NewLocal(isolate), element);
}

void ScriptCustomElementDefinition::RunDisconnectedCallback(Element* element) {
  if (!script_state_->ContextIsValid())
    return;
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();
  RunCallback(disconnected_callback_.NewLocal(isolate), element);
}

void ScriptCustomElementDefinition::RunAdoptedCallback(Element* element,
                                                       Document* old_owner,
                                                       Document* new_owner) {
  if (!script_state_->ContextIsValid())
    return;
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();
  v8::Local<v8::Value> argv[] = {
      ToV8(old_owner, script_state_->GetContext()->Global(), isolate),
      ToV8(new_owner, script_state_->GetContext()->Global(), isolate)};
  RunCallback(adopted_callback_.NewLocal(isolate), element, base::size(argv),
              argv);
}

void ScriptCustomElementDefinition::RunAttributeChangedCallback(
    Element* element,
    const QualifiedName& name,
    const AtomicString& old_value,
    const AtomicString& new_value) {
  if (!script_state_->ContextIsValid())
    return;
  ScriptState::Scope scope(script_state_.get());
  v8::Isolate* isolate = script_state_->GetIsolate();
  v8::Local<v8::Value> argv[] = {
      V8String(isolate, name.LocalName()), V8StringOrNull(isolate, old_value),
      V8StringOrNull(isolate, new_value),
      V8StringOrNull(isolate, name.NamespaceURI()),
  };
  RunCallback(attribute_changed_callback_.NewLocal(isolate), element,
              base::size(argv), argv);
}

}  // namespace blink
