// Copyright 2020 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/platform/bindings/idl_member_installer.h"

#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"

namespace blink {

namespace bindings {

namespace {

template <typename Config>
bool DoesWorldMatch(const Config& config, const DOMWrapperWorld& world) {
  const unsigned world_bit = static_cast<unsigned>(
      world.IsMainWorld() ? IDLMemberInstaller::FlagWorld::kMainWorld
                          : IDLMemberInstaller::FlagWorld::kNonMainWorlds);
  return config.world & world_bit;
}

enum class FunctionKind {
  kAttributeGet,
  kAttributeSet,
  kOperation,
};

template <FunctionKind kind, typename Config>
v8::FunctionCallback GetConfigCallback(const Config& config);
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kAttributeGet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return config.callback_for_get;
}
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kAttributeSet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return config.callback_for_set;
}
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kOperation>(
    const IDLMemberInstaller::OperationConfig& config) {
  return config.callback;
}

template <FunctionKind kind, typename Config>
int GetConfigLength(const Config& config);
template <>
int GetConfigLength<FunctionKind::kAttributeGet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return 0;
}
template <>
int GetConfigLength<FunctionKind::kAttributeSet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return 1;
}
template <>
int GetConfigLength<FunctionKind::kOperation>(
    const IDLMemberInstaller::OperationConfig& config) {
  return config.length;
}

template <FunctionKind kind, typename Config>
IDLMemberInstaller::FlagCrossOriginCheck GetConfigCrossOriginCheck(
    const Config& config);
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kAttributeGet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
      config.cross_origin_check_for_get);
}
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kAttributeSet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
      config.cross_origin_check_for_set);
}
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kOperation>(
    const IDLMemberInstaller::OperationConfig& config) {
  return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
      config.cross_origin_check);
}

template <FunctionKind kind, typename Config>
v8::SideEffectType GetConfigSideEffect(const Config& config);
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kAttributeGet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return static_cast<v8::SideEffectType>(config.v8_side_effect);
}
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kAttributeSet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return v8::SideEffectType::kHasSideEffect;
}
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kOperation>(
    const IDLMemberInstaller::OperationConfig& config) {
  return static_cast<v8::SideEffectType>(config.v8_side_effect);
}

template <FunctionKind kind, typename Config>
V8PrivateProperty::CachedAccessor GetConfigV8CachedAccessor(
    const Config& config);
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kAttributeGet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return static_cast<V8PrivateProperty::CachedAccessor>(
      config.v8_cached_accessor);
}
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kAttributeSet>(
    const IDLMemberInstaller::AttributeConfig& config) {
  return V8PrivateProperty::CachedAccessor::kNone;
}
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kOperation>(
    const IDLMemberInstaller::OperationConfig& config) {
  return V8PrivateProperty::CachedAccessor::kNone;
}

template <FunctionKind kind, typename Config>
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Signature> signature,
    v8::Local<v8::String> name,
    const Config& config,
    const v8::CFunction* v8_c_function = nullptr) {
  v8::FunctionCallback callback = GetConfigCallback<kind>(config);
  if (!callback)
    return v8::Local<v8::FunctionTemplate>();

  int length = GetConfigLength<kind>(config);
  v8::SideEffectType v8_side_effect = GetConfigSideEffect<kind>(config);
  V8PrivateProperty::CachedAccessor v8_cached_accessor =
      GetConfigV8CachedAccessor<kind>(config);

  v8::Local<v8::FunctionTemplate> function_template;
  if (v8_cached_accessor == V8PrivateProperty::CachedAccessor::kNone ||
      (v8_cached_accessor ==
           V8PrivateProperty::CachedAccessor::kWindowDocument &&
       !world.IsMainWorld())) {
    function_template = v8::FunctionTemplate::New(
        isolate, callback, v8::Local<v8::Value>(), signature, length,
        v8::ConstructorBehavior::kThrow, v8_side_effect, v8_c_function);
  } else {
    function_template = v8::FunctionTemplate::NewWithCache(
        isolate, callback,
        V8PrivateProperty::GetCachedAccessor(isolate, v8_cached_accessor)
            .GetPrivate(),
        v8::Local<v8::Value>(), signature, length, v8_side_effect);
    function_template->RemovePrototype();
  }

  function_template->SetClassName(name);
  function_template->SetAcceptAnyReceiver(
      GetConfigCrossOriginCheck<kind>(config) ==
      IDLMemberInstaller::FlagCrossOriginCheck::kDoNotCheck);

  return function_template;
}

template <FunctionKind kind, typename Config>
v8::Local<v8::Function> CreateFunction(v8::Isolate* isolate,
                                       v8::Local<v8::Context> context,
                                       const DOMWrapperWorld& world,
                                       v8::Local<v8::Signature> signature,
                                       v8::Local<v8::String> name,
                                       const Config& config) {
  if (!GetConfigCallback<kind>(config))
    return v8::Local<v8::Function>();

  return CreateFunctionTemplate<kind>(isolate, world, signature, name, config)
      ->GetFunction(context)
      .ToLocalChecked();
}

void InstallAttribute(v8::Isolate* isolate,
                      const DOMWrapperWorld& world,
                      v8::Local<v8::Template> instance_template,
                      v8::Local<v8::Template> prototype_template,
                      v8::Local<v8::Template> interface_template,
                      v8::Local<v8::Signature> signature,
                      const IDLMemberInstaller::AttributeConfig& config) {
  if (!DoesWorldMatch(config, world))
    return;

  IDLMemberInstaller::FlagLocation location =
      static_cast<IDLMemberInstaller::FlagLocation>(config.location);
  if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
          config.receiver_check) ==
          IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
      location == IDLMemberInstaller::FlagLocation::kInterface)
    signature = v8::Local<v8::Signature>();

  StringView name_as_view(config.name);
  v8::Local<v8::String> name = V8AtomicString(isolate, name_as_view);
  v8::Local<v8::String> get_name = V8AtomicString(
      isolate, static_cast<String>(StringView("get ", 4) + name_as_view));
  v8::Local<v8::String> set_name = V8AtomicString(
      isolate, static_cast<String>(StringView("set ", 4) + name_as_view));
  v8::Local<v8::FunctionTemplate> get_func =
      CreateFunctionTemplate<FunctionKind::kAttributeGet>(
          isolate, world, signature, get_name, config);
  v8::Local<v8::FunctionTemplate> set_func =
      CreateFunctionTemplate<FunctionKind::kAttributeSet>(
          isolate, world, signature, set_name, config);

  v8::Local<v8::Template> target_template;
  switch (location) {
    case IDLMemberInstaller::FlagLocation::kInstance:
      target_template = instance_template;
      break;
    case IDLMemberInstaller::FlagLocation::kPrototype:
      target_template = prototype_template;
      break;
    case IDLMemberInstaller::FlagLocation::kInterface:
      target_template = interface_template;
      break;
    default:
      NOTREACHED();
  }
  target_template->SetAccessorProperty(
      name, get_func, set_func,
      static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}

void InstallAttribute(v8::Isolate* isolate,
                      v8::Local<v8::Context> context,
                      const DOMWrapperWorld& world,
                      v8::Local<v8::Object> instance_object,
                      v8::Local<v8::Object> prototype_object,
                      v8::Local<v8::Object> interface_object,
                      v8::Local<v8::Signature> signature,
                      const IDLMemberInstaller::AttributeConfig& config) {
  if (!DoesWorldMatch(config, world))
    return;

  IDLMemberInstaller::FlagLocation location =
      static_cast<IDLMemberInstaller::FlagLocation>(config.location);
  if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
          config.receiver_check) ==
          IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
      location == IDLMemberInstaller::FlagLocation::kInterface)
    signature = v8::Local<v8::Signature>();

  StringView name_as_view(config.name);
  v8::Local<v8::String> name = V8AtomicString(isolate, name_as_view);
  v8::Local<v8::String> get_name = V8AtomicString(
      isolate, static_cast<String>(StringView("get ", 4) + name_as_view));
  v8::Local<v8::String> set_name = V8AtomicString(
      isolate, static_cast<String>(StringView("set ", 4) + name_as_view));
  v8::Local<v8::Function> get_func =
      CreateFunction<FunctionKind::kAttributeGet>(isolate, context, world,
                                                  signature, get_name, config);
  v8::Local<v8::Function> set_func =
      CreateFunction<FunctionKind::kAttributeSet>(isolate, context, world,
                                                  signature, set_name, config);

  v8::Local<v8::Object> target_object;
  switch (location) {
    case IDLMemberInstaller::FlagLocation::kInstance:
      target_object = instance_object;
      break;
    case IDLMemberInstaller::FlagLocation::kPrototype:
      target_object = prototype_object;
      break;
    case IDLMemberInstaller::FlagLocation::kInterface:
      target_object = interface_object;
      break;
    default:
      NOTREACHED();
  }
  target_object->SetAccessorProperty(
      name, get_func, set_func,
      static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}

void InstallOperation(v8::Isolate* isolate,
                      const DOMWrapperWorld& world,
                      v8::Local<v8::Template> instance_template,
                      v8::Local<v8::Template> prototype_template,
                      v8::Local<v8::Template> interface_template,
                      v8::Local<v8::Signature> signature,
                      const IDLMemberInstaller::OperationConfig& config,
                      const v8::CFunction* v8_c_function = nullptr) {
  if (!DoesWorldMatch(config, world))
    return;

  IDLMemberInstaller::FlagLocation location =
      static_cast<IDLMemberInstaller::FlagLocation>(config.location);
  if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
          config.receiver_check) ==
          IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
      location == IDLMemberInstaller::FlagLocation::kInterface)
    signature = v8::Local<v8::Signature>();

  v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
  v8::Local<v8::FunctionTemplate> func =
      CreateFunctionTemplate<FunctionKind::kOperation>(
          isolate, world, signature, name, config, v8_c_function);

  v8::Local<v8::Template> target_template;
  switch (location) {
    case IDLMemberInstaller::FlagLocation::kInstance:
      target_template = instance_template;
      break;
    case IDLMemberInstaller::FlagLocation::kPrototype:
      target_template = prototype_template;
      break;
    case IDLMemberInstaller::FlagLocation::kInterface:
      target_template = interface_template;
      break;
    default:
      NOTREACHED();
  }
  target_template->Set(
      name, func,
      static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}

void InstallOperation(v8::Isolate* isolate,
                      v8::Local<v8::Context> context,
                      const DOMWrapperWorld& world,
                      v8::Local<v8::Object> instance_object,
                      v8::Local<v8::Object> prototype_object,
                      v8::Local<v8::Object> interface_object,
                      v8::Local<v8::Signature> signature,
                      const IDLMemberInstaller::OperationConfig& config) {
  if (!DoesWorldMatch(config, world))
    return;

  IDLMemberInstaller::FlagLocation location =
      static_cast<IDLMemberInstaller::FlagLocation>(config.location);
  if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
          config.receiver_check) ==
          IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
      location == IDLMemberInstaller::FlagLocation::kInterface)
    signature = v8::Local<v8::Signature>();

  v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
  v8::Local<v8::Function> func = CreateFunction<FunctionKind::kOperation>(
      isolate, context, world, signature, name, config);

  v8::Local<v8::Object> target_object;
  switch (location) {
    case IDLMemberInstaller::FlagLocation::kInstance:
      target_object = instance_object;
      break;
    case IDLMemberInstaller::FlagLocation::kPrototype:
      target_object = prototype_object;
      break;
    case IDLMemberInstaller::FlagLocation::kInterface:
      target_object = interface_object;
      break;
    default:
      NOTREACHED();
  }
  target_object
      ->DefineOwnProperty(
          context, name, func,
          static_cast<v8::PropertyAttribute>(config.v8_property_attribute))
      .ToChecked();
}

}  // namespace

// static
void IDLMemberInstaller::InstallAttributes(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const AttributeConfig> configs) {
  for (const auto& config : configs) {
    InstallAttribute(isolate, world, instance_template, prototype_template,
                     interface_template, signature, config);
  }
}

// static
void IDLMemberInstaller::InstallAttributes(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance_object,
    v8::Local<v8::Object> prototype_object,
    v8::Local<v8::Object> interface_object,
    v8::Local<v8::Signature> signature,
    base::span<const AttributeConfig> configs) {
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  for (const auto& config : configs) {
    InstallAttribute(isolate, context, world, instance_object, prototype_object,
                     interface_object, signature, config);
  }
}

// static
void IDLMemberInstaller::InstallConstants(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const ConstantCallbackConfig> configs) {
  const bool has_prototype_template = !prototype_template.IsEmpty();
  const v8::PropertyAttribute v8_property_attribute =
      static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
  for (const auto& config : configs) {
    v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
    if (has_prototype_template) {
      prototype_template->SetLazyDataProperty(
          name, config.callback, v8::Local<v8::Value>(), v8_property_attribute,
          v8::SideEffectType::kHasNoSideEffect);
    }
    interface_template->SetLazyDataProperty(
        name, config.callback, v8::Local<v8::Value>(), v8_property_attribute,
        v8::SideEffectType::kHasNoSideEffect);
  }
}

// static
void IDLMemberInstaller::InstallConstants(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const ConstantValueConfig> configs) {
  const bool has_prototype_template = !prototype_template.IsEmpty();
  const v8::PropertyAttribute v8_property_attribute =
      static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
  for (const auto& config : configs) {
    v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
    v8::Local<v8::Integer> value;
    if (config.value < 0) {
      int32_t i32_value = static_cast<int32_t>(config.value);
      DCHECK_EQ(static_cast<int64_t>(i32_value), config.value);
      value = v8::Integer::New(isolate, i32_value);
    } else {
      uint32_t u32_value = static_cast<uint32_t>(config.value);
      DCHECK_EQ(static_cast<int64_t>(u32_value), config.value);
      value = v8::Integer::NewFromUnsigned(isolate, u32_value);
    }
    if (has_prototype_template) {
      prototype_template->Set(name, value, v8_property_attribute);
    }
    interface_template->Set(name, value, v8_property_attribute);
  }
}

// static
void IDLMemberInstaller::InstallOperations(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const OperationConfig> configs) {
  for (const auto& config : configs) {
    InstallOperation(isolate, world, instance_template, prototype_template,
                     interface_template, signature, config);
  }
}

// static
void IDLMemberInstaller::InstallOperations(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance_object,
    v8::Local<v8::Object> prototype_object,
    v8::Local<v8::Object> interface_object,
    v8::Local<v8::Signature> signature,
    base::span<const OperationConfig> configs) {
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  for (const auto& config : configs) {
    InstallOperation(isolate, context, world, instance_object, prototype_object,
                     interface_object, signature, config);
  }
}

// static
void IDLMemberInstaller::InstallOperations(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const NoAllocDirectCallOperationConfig> configs) {
  for (const auto& config : configs) {
    InstallOperation(isolate, world, instance_template, prototype_template,
                     interface_template, signature, config.operation_config,
                     &config.v8_c_function);
  }
}

// static
void IDLMemberInstaller::InstallExposedConstructs(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Template> instance_template,
    v8::Local<v8::Template> prototype_template,
    v8::Local<v8::Template> interface_template,
    v8::Local<v8::Signature> signature,
    base::span<const ExposedConstructConfig> configs) {
  for (const auto& config : configs) {
    v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
    instance_template->SetLazyDataProperty(
        name, config.callback, v8::Local<v8::Value>(), v8::DontEnum,
        v8::SideEffectType::kHasNoSideEffect);
  }
}

// static
void IDLMemberInstaller::InstallExposedConstructs(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance_object,
    v8::Local<v8::Object> prototype_object,
    v8::Local<v8::Object> interface_object,
    v8::Local<v8::Signature> signature,
    base::span<const ExposedConstructConfig> configs) {
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  for (const auto& config : configs) {
    instance_object
        ->SetLazyDataProperty(context, V8AtomicString(isolate, config.name),
                              config.callback, v8::Local<v8::Value>(),
                              v8::DontEnum,
                              v8::SideEffectType::kHasNoSideEffect)
        .ToChecked();
  }
}

}  // namespace bindings

}  // namespace blink
