// 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 "extensions/renderer/chrome_setting.h"

#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "extensions/renderer/bindings/api_event_handler.h"
#include "extensions/renderer/bindings/api_request_handler.h"
#include "extensions/renderer/bindings/api_signature.h"
#include "extensions/renderer/bindings/api_type_reference_map.h"
#include "extensions/renderer/bindings/binding_access_checker.h"
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"

namespace extensions {

v8::Local<v8::Object> ChromeSetting::Create(
    v8::Isolate* isolate,
    const std::string& property_name,
    const base::ListValue* property_values,
    APIRequestHandler* request_handler,
    APIEventHandler* event_handler,
    APITypeReferenceMap* type_refs,
    const BindingAccessChecker* access_checker) {
  std::string pref_name;
  CHECK(property_values->GetString(0u, &pref_name));
  const base::DictionaryValue* value_spec = nullptr;
  CHECK(property_values->GetDictionary(1u, &value_spec));

  gin::Handle<ChromeSetting> handle = gin::CreateHandle(
      isolate, new ChromeSetting(request_handler, event_handler, type_refs,
                                 access_checker, pref_name, *value_spec));
  return handle.ToV8().As<v8::Object>();
}

ChromeSetting::ChromeSetting(APIRequestHandler* request_handler,
                             APIEventHandler* event_handler,
                             const APITypeReferenceMap* type_refs,
                             const BindingAccessChecker* access_checker,
                             const std::string& pref_name,
                             const base::DictionaryValue& set_value_spec)
    : request_handler_(request_handler),
      event_handler_(event_handler),
      type_refs_(type_refs),
      access_checker_(access_checker),
      pref_name_(pref_name),
      argument_spec_(ArgumentType::OBJECT) {
  // The set() call takes an object { value: { type: <t> }, ... }, where <t>
  // is the custom set() argument specified above by value_spec.
  ArgumentSpec::PropertiesMap properties;
  {
    auto scope_spec = base::MakeUnique<ArgumentSpec>(ArgumentType::REF);
    scope_spec->set_ref("types.ChromeSettingScope");
    scope_spec->set_optional(true);
    properties["scope"] = std::move(scope_spec);
  }
  properties["value"] = base::MakeUnique<ArgumentSpec>(set_value_spec);
  argument_spec_.set_properties(std::move(properties));
}

ChromeSetting::~ChromeSetting() = default;

gin::WrapperInfo ChromeSetting::kWrapperInfo = {gin::kEmbedderNativeGin};

gin::ObjectTemplateBuilder ChromeSetting::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return Wrappable<ChromeSetting>::GetObjectTemplateBuilder(isolate)
      .SetMethod("get", &ChromeSetting::Get)
      .SetMethod("set", &ChromeSetting::Set)
      .SetMethod("clear", &ChromeSetting::Clear)
      .SetProperty("onChange", &ChromeSetting::GetOnChangeEvent);
}

void ChromeSetting::Get(gin::Arguments* arguments) {
  HandleFunction("get", arguments);
}

void ChromeSetting::Set(gin::Arguments* arguments) {
  v8::Isolate* isolate = arguments->isolate();
  v8::HandleScope handle_scope(isolate);
  v8::Local<v8::Context> context = arguments->GetHolderCreationContext();

  v8::Local<v8::Value> value = arguments->PeekNext();
  // The set schema included in the Schema object is generic, since it varies
  // per-setting. However, this is only ever for a single setting, so we can
  // enforce the types more thoroughly.
  std::string error;
  if (!value.IsEmpty() && !argument_spec_.ParseArgument(
                              context, value, *type_refs_, nullptr, &error)) {
    arguments->ThrowTypeError("Invalid invocation");
    return;
  }
  HandleFunction("set", arguments);
}

void ChromeSetting::Clear(gin::Arguments* arguments) {
  HandleFunction("clear", arguments);
}

v8::Local<v8::Value> ChromeSetting::GetOnChangeEvent(
    gin::Arguments* arguments) {
  v8::Isolate* isolate = arguments->isolate();
  v8::Local<v8::Context> context = arguments->GetHolderCreationContext();
  v8::Local<v8::Object> wrapper = GetWrapper(isolate).ToLocalChecked();
  v8::Local<v8::Private> key = v8::Private::ForApi(
      isolate, gin::StringToSymbol(isolate, "onChangeEvent"));
  v8::Local<v8::Value> event;
  if (!wrapper->GetPrivate(context, key).ToLocal(&event)) {
    NOTREACHED();
    return v8::Local<v8::Value>();
  }

  DCHECK(!event.IsEmpty());
  if (event->IsUndefined()) {
    bool supports_filters = false;
    bool supports_lazy_listeners = true;
    event = event_handler_->CreateEventInstance(
        base::StringPrintf("types.ChromeSetting.%s.onChange",
                           pref_name_.c_str()),
        supports_filters, supports_lazy_listeners, binding::kNoListenerMax,
        true, context);
    v8::Maybe<bool> set_result = wrapper->SetPrivate(context, key, event);
    if (!set_result.IsJust() || !set_result.FromJust()) {
      NOTREACHED();
      return v8::Local<v8::Value>();
    }
  }
  return event;
}

void ChromeSetting::HandleFunction(const std::string& method_name,
                                   gin::Arguments* arguments) {
  v8::Isolate* isolate = arguments->isolate();
  v8::HandleScope handle_scope(isolate);
  v8::Local<v8::Context> context = arguments->GetHolderCreationContext();

  std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll();

  std::string full_name = "types.ChromeSetting." + method_name;

  if (!access_checker_->HasAccessOrThrowError(context, full_name))
    return;

  std::unique_ptr<base::ListValue> converted_arguments;
  v8::Local<v8::Function> callback;
  std::string error;
  if (!type_refs_->GetTypeMethodSignature(full_name)->ParseArgumentsToJSON(
          context, argument_list, *type_refs_, &converted_arguments, &callback,
          &error)) {
    arguments->ThrowTypeError("Invalid invocation");
    return;
  }

  converted_arguments->Insert(0u, base::MakeUnique<base::Value>(pref_name_));
  request_handler_->StartRequest(
      context, full_name, std::move(converted_arguments), callback,
      v8::Local<v8::Function>(), binding::RequestThread::UI);
}

}  // namespace extensions
