// Copyright 2014 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/module_system.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "extensions/common/extension.h"
#include "extensions/common/extensions_client.h"
#include "extensions/renderer/console.h"
#include "extensions/renderer/safe_builtins.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_context_set.h"
#include "extensions/renderer/source_map.h"
#include "extensions/renderer/v8_helpers.h"
#include "gin/converter.h"
#include "third_party/blink/public/web/web_context_features.h"
#include "third_party/blink/public/web/web_frame.h"

namespace extensions {

using namespace v8_helpers;

namespace {

const char kModuleSystem[] = "module_system";
const char kModuleName[] = "module_name";
const char kModuleField[] = "module_field";
const char kModulesField[] = "modules";

// Logs an error for the calling context in preparation for potentially
// crashing the renderer, with some added metadata about the context:
//  - Its type (blessed, unblessed, etc).
//  - Whether it's valid.
//  - The extension ID, if one exists.
// Crashing won't happen in stable/beta releases, but is encouraged to happen
// in the less stable released to catch errors early.
void Fatal(ScriptContext* context, const std::string& message) {
  // Prepend some context metadata.
  std::string full_message = "(";
  if (!context->is_valid())
    full_message += "Invalid ";
  full_message += context->GetContextTypeDescription();
  full_message += " context";
  if (context->extension()) {
    full_message += " for ";
    full_message += context->extension()->id();
  }
  full_message += ") ";
  full_message += message;

  ExtensionsClient* client = ExtensionsClient::Get();
  if (client->ShouldSuppressFatalErrors()) {
    console::AddMessage(context, blink::mojom::ConsoleMessageLevel::kError,
                        full_message);
    client->RecordDidSuppressFatalError();
  } else {
    console::Fatal(context, full_message);
  }
}

void Warn(v8::Isolate* isolate, const std::string& message) {
  ScriptContext* script_context =
      ScriptContextSet::GetContextByV8Context(isolate->GetCurrentContext());
  console::AddMessage(script_context,
                      blink::mojom::ConsoleMessageLevel::kWarning, message);
}

// Default exception handler which logs the exception.
class DefaultExceptionHandler : public ModuleSystem::ExceptionHandler {
 public:
  explicit DefaultExceptionHandler(ScriptContext* context)
      : ModuleSystem::ExceptionHandler(context) {}

  // Fatally dumps the debug info from |try_catch| to the console.
  // Make sure this is never used for exceptions that originate in external
  // code!
  void HandleUncaughtException(const v8::TryCatch& try_catch) override {
    v8::HandleScope handle_scope(context_->isolate());
    std::string stack_trace = "<stack trace unavailable>";
    v8::Local<v8::Value> v8_stack_trace;
    if (try_catch.StackTrace(context_->v8_context()).ToLocal(&v8_stack_trace)) {
      v8::String::Utf8Value stack_value(context_->isolate(), v8_stack_trace);
      if (*stack_value)
        stack_trace.assign(*stack_value, stack_value.length());
      else
        stack_trace = "<could not convert stack trace to string>";
    }
    Fatal(context_, CreateExceptionString(try_catch) + "{" + stack_trace + "}");
  }
};

// Sets a property on the "exports" object for bindings. Called by JS with
// exports.$set(<key>, <value>).
void SetExportsProperty(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::Local<v8::Object> obj = args.This();
  CHECK_EQ(2, args.Length());
  CHECK(args[0]->IsString());
  v8::Maybe<bool> result =
      obj->DefineOwnProperty(args.GetIsolate()->GetCurrentContext(),
                             args[0].As<v8::String>(), args[1], v8::ReadOnly);
  if (!result.FromMaybe(false))
    LOG(ERROR) << "Failed to set private property on the export.";
}

bool ContextNeedsMojoBindings(ScriptContext* context) {
  // Mojo is only used from JS by some APIs so a context only needs the mojo
  // bindings if at least one is available.
  //
  // Prefer to use Mojo from C++ if possible rather than adding to this list.
  static const char* const kApisRequiringMojo[] = {
      "mediaPerceptionPrivate", "mimeHandlerPrivate", "mojoPrivate",
  };

  for (const auto* api : kApisRequiringMojo) {
    if (context->GetAvailability(api).is_available())
      return true;
  }
  return false;
}

}  // namespace

std::string ModuleSystem::ExceptionHandler::CreateExceptionString(
    const v8::TryCatch& try_catch) {
  v8::Local<v8::Message> message(try_catch.Message());
  if (message.IsEmpty()) {
    return "try_catch has no message";
  }

  std::string resource_name = "<unknown resource>";
  if (!message->GetScriptOrigin().ResourceName().IsEmpty()) {
    v8::String::Utf8Value resource_name_v8(
        context_->isolate(), message->GetScriptOrigin().ResourceName());
    resource_name.assign(*resource_name_v8, resource_name_v8.length());
  }

  std::string error_message = "<no error message>";
  if (!message->Get().IsEmpty()) {
    v8::String::Utf8Value error_message_v8(context_->isolate(), message->Get());
    error_message.assign(*error_message_v8, error_message_v8.length());
  }

  int line_number = 0;
  if (context_) {  // |context_| can be null in unittests.
    auto maybe = message->GetLineNumber(context_->v8_context());
    line_number = maybe.IsJust() ? maybe.FromJust() : 0;
  }
  return base::StringPrintf("%s:%d: %s",
                            resource_name.c_str(),
                            line_number,
                            error_message.c_str());
}

ModuleSystem::ModuleSystem(ScriptContext* context, const SourceMap* source_map)
    : ObjectBackedNativeHandler(context),
      context_(context),
      source_map_(source_map),
      natives_enabled_(0),
      exception_handler_(new DefaultExceptionHandler(context)) {
  v8::Local<v8::Object> global(context->v8_context()->Global());
  v8::Isolate* isolate = context->isolate();
  SetPrivate(global, kModulesField, v8::Object::New(isolate));
  SetPrivate(global, kModuleSystem, v8::External::New(isolate, this));

  if (context_->GetRenderFrame() &&
      context_->context_type() == Feature::BLESSED_EXTENSION_CONTEXT &&
      ContextNeedsMojoBindings(context_)) {
    blink::WebContextFeatures::EnableMojoJS(context->v8_context(), true);
  }
}

ModuleSystem::~ModuleSystem() {
}

void ModuleSystem::AddRoutes() {
  RouteHandlerFunction(
      "require",
      base::BindRepeating(&ModuleSystem::RequireForJs, base::Unretained(this)));
  RouteHandlerFunction("requireNative",
                       base::BindRepeating(&ModuleSystem::RequireNative,
                                           base::Unretained(this)));
  RouteHandlerFunction(
      "loadScript",
      base::BindRepeating(&ModuleSystem::LoadScript, base::Unretained(this)));
  RouteHandlerFunction("privates", base::BindRepeating(&ModuleSystem::Private,
                                                       base::Unretained(this)));
}

void ModuleSystem::Invalidate() {
  // Clear the module system properties from the global context. It's polite,
  // and we use this as a signal in lazy handlers that we no longer exist.
  {
    v8::HandleScope scope(GetIsolate());
    v8::Local<v8::Object> global = context()->v8_context()->Global();
    DeletePrivate(global, kModulesField);
    DeletePrivate(global, kModuleSystem);
  }

  // Invalidate all active and clobbered NativeHandlers we own.
  for (const auto& handler : native_handler_map_)
    handler.second->Invalidate();
  for (const auto& clobbered_handler : clobbered_native_handlers_)
    clobbered_handler->Invalidate();

  ObjectBackedNativeHandler::Invalidate();
}

ModuleSystem::NativesEnabledScope::NativesEnabledScope(
    ModuleSystem* module_system)
    : module_system_(module_system) {
  module_system_->natives_enabled_++;
}

ModuleSystem::NativesEnabledScope::~NativesEnabledScope() {
  module_system_->natives_enabled_--;
  CHECK_GE(module_system_->natives_enabled_, 0);
}

void ModuleSystem::HandleException(const v8::TryCatch& try_catch) {
  exception_handler_->HandleUncaughtException(try_catch);
}

v8::MaybeLocal<v8::Object> ModuleSystem::Require(
    const std::string& module_name) {
  v8::Local<v8::String> v8_module_name;
  if (!ToV8String(GetIsolate(), module_name, &v8_module_name))
    return v8::MaybeLocal<v8::Object>();
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Value> value =
      RequireForJsInner(v8_module_name, true /* create */);
  if (value.IsEmpty() || !value->IsObject())
    return v8::MaybeLocal<v8::Object>();
  return handle_scope.Escape(value.As<v8::Object>());
}

void ModuleSystem::RequireForJs(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  if (!args[0]->IsString()) {
    NOTREACHED() << "require() called with a non-string argument";
    return;
  }
  v8::Local<v8::String> module_name = args[0].As<v8::String>();
  args.GetReturnValue().Set(RequireForJsInner(module_name, true /* create */));
}

v8::Local<v8::Value> ModuleSystem::RequireForJsInner(
    v8::Local<v8::String> module_name,
    bool create) {
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::Object> global(context()->v8_context()->Global());

  // The module system might have been deleted. This can happen if a different
  // context keeps a reference to us, but our frame is destroyed (e.g.
  // background page keeps reference to chrome object in a closed popup).
  v8::Local<v8::Value> modules_value;
  if (!GetPrivate(global, kModulesField, &modules_value) ||
      modules_value->IsUndefined()) {
    Warn(GetIsolate(), "Extension view no longer exists");
    return v8::Undefined(GetIsolate());
  }

  v8::Local<v8::Object> modules(v8::Local<v8::Object>::Cast(modules_value));
  v8::Local<v8::Value> exports;
  if (!GetPrivateProperty(v8_context, modules, module_name, &exports) ||
      !exports->IsUndefined())
    return handle_scope.Escape(exports);

  if (!create)
    return v8::Undefined(GetIsolate());

  exports = LoadModule(*v8::String::Utf8Value(GetIsolate(), module_name));
  SetPrivateProperty(v8_context, modules, module_name, exports);
  return handle_scope.Escape(exports);
}

void ModuleSystem::CallModuleMethodSafe(const std::string& module_name,
                                        const std::string& method_name) {
  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Value> no_args;
  CallModuleMethodSafe(module_name, method_name, 0, &no_args,
                       ScriptInjectionCallback::CompleteCallback());
}

void ModuleSystem::CallModuleMethodSafe(
    const std::string& module_name,
    const std::string& method_name,
    std::vector<v8::Local<v8::Value>>* args) {
  CallModuleMethodSafe(module_name, method_name, args->size(), args->data(),
                       ScriptInjectionCallback::CompleteCallback());
}

void ModuleSystem::CallModuleMethodSafe(const std::string& module_name,
                                        const std::string& method_name,
                                        int argc,
                                        v8::Local<v8::Value> argv[]) {
  CallModuleMethodSafe(module_name, method_name, argc, argv,
                       ScriptInjectionCallback::CompleteCallback());
}

void ModuleSystem::CallModuleMethodSafe(
    const std::string& module_name,
    const std::string& method_name,
    int argc,
    v8::Local<v8::Value> argv[],
    const ScriptInjectionCallback::CompleteCallback& callback) {
  TRACE_EVENT2("v8", "v8.callModuleMethodSafe", "module_name", module_name,
               "method_name", method_name);

  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::Function> function =
      GetModuleFunction(module_name, method_name);
  if (function.IsEmpty()) {
    // This can legitimately happen when the module hasn't been loaded in the
    // context (since GetModuleFunction() does not load an unloaded module).
    // Typically, we won't do this, but we can in the case of, e.g., dispatching
    // events (where we'll try to dispatch to each context in a process). In
    // these cases, though, we can know that there are no listeners registered,
    // since the event module hasn't been loaded.
    return;
  }

  {
    v8::TryCatch try_catch(GetIsolate());
    try_catch.SetCaptureMessage(true);
    context_->SafeCallFunction(function, argc, argv, callback);
    if (try_catch.HasCaught())
      HandleException(try_catch);
  }
}

void ModuleSystem::RegisterNativeHandler(
    const std::string& name,
    std::unique_ptr<NativeHandler> native_handler) {
  ClobberExistingNativeHandler(name);
  native_handler_map_[name] = std::move(native_handler);
}

void ModuleSystem::OverrideNativeHandlerForTest(const std::string& name) {
  ClobberExistingNativeHandler(name);
  overridden_native_handlers_.insert(name);
}

// static
void ModuleSystem::NativeLazyFieldGetter(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  LazyFieldGetterInner(property.As<v8::String>(), info,
                       &ModuleSystem::RequireNativeFromString);
}

// static
void ModuleSystem::LazyFieldGetter(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  LazyFieldGetterInner(property.As<v8::String>(), info, &ModuleSystem::Require);
}

// static
void ModuleSystem::LazyFieldGetterInner(
    v8::Local<v8::String> property,
    const v8::PropertyCallbackInfo<v8::Value>& info,
    RequireFunction require_function) {
  base::ElapsedTimer timer;
  CHECK(!info.Data().IsEmpty());
  CHECK(info.Data()->IsObject());
  v8::Isolate* isolate = info.GetIsolate();
  v8::HandleScope handle_scope(isolate);
  v8::Local<v8::Object> parameters = v8::Local<v8::Object>::Cast(info.Data());
  // This context should be the same as context()->v8_context().
  v8::Local<v8::Context> context = parameters->CreationContext();
  v8::Local<v8::Object> global(context->Global());
  v8::Local<v8::Value> module_system_value;
  if (!GetPrivate(context, global, kModuleSystem, &module_system_value) ||
      !module_system_value->IsExternal()) {
    // ModuleSystem has been deleted.
    // TODO(kalman): See comment in header file.
    Warn(isolate,
         "Module system has been deleted, does extension view exist?");
    return;
  }

  ModuleSystem* module_system = static_cast<ModuleSystem*>(
      v8::Local<v8::External>::Cast(module_system_value)->Value());

  v8::Local<v8::Value> v8_module_name;
  if (!GetPrivateProperty(context, parameters, kModuleName, &v8_module_name)) {
    Warn(isolate, "Cannot find module.");
    return;
  }
  std::string name = *v8::String::Utf8Value(isolate, v8_module_name);

  // As part of instantiating a module, we delete the getter and replace it with
  // the property directly. If we're trying to load the same module a second
  // time, it means something went wrong. Bail out early rather than going
  // through the initialization process again (since bindings may not expect to
  // run multiple times).
  if (!module_system->loaded_modules_.insert(name).second) {
    Warn(isolate, "Previous API instantiation failed.");
    return;
  }

  // Switch to our v8 context because we need functions created while running
  // the require()d module to belong to our context, not the current one.
  v8::Context::Scope context_scope(context);
  NativesEnabledScope natives_enabled_scope(module_system);

  v8::TryCatch try_catch(isolate);
  v8::Local<v8::Value> module_value;
  if (!(module_system->*require_function)(name).ToLocal(&module_value)) {
    module_system->HandleException(try_catch);
    return;
  }

  v8::Local<v8::Object> module = v8::Local<v8::Object>::Cast(module_value);
  v8::Local<v8::Value> field_value;
  if (!GetPrivateProperty(context, parameters, kModuleField, &field_value)) {
    module_system->HandleException(try_catch);
    return;
  }
  v8::Local<v8::String> field;
  if (!field_value->ToString(context).ToLocal(&field)) {
    module_system->HandleException(try_catch);
    return;
  }

  if (!IsTrue(module->Has(context, field))) {
    std::string field_str = *v8::String::Utf8Value(isolate, field);
    Fatal(module_system->context_,
          "Lazy require of " + name + "." + field_str + " did not set the " +
              field_str + " field");
    return;
  }

  v8::Local<v8::Value> new_field;
  if (!GetProperty(context, module, field, &new_field)) {
    module_system->HandleException(try_catch);
    return;
  }

  // Ok for it to be undefined, among other things it's how bindings signify
  // that the extension doesn't have permission to use them.
  CHECK(!new_field.IsEmpty());

  // Delete the getter and set this field to |new_field| so the same object is
  // returned every time a certain API is accessed.
  v8::Local<v8::Value> val = info.This();
  if (val->IsObject()) {
    v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(val);
    auto maybe_deleted = object->Delete(context, property);
    if (!maybe_deleted.IsJust()) {
      // In theory, deletion should never result in throwing an error. But
      // crazier things have happened.
      NOTREACHED();
      return;
    }
    if (!maybe_deleted.FromJust()) {
      // Deletion can *fail* in certain cases, such as when the script does
      // Object.freeze(chrome).
      return;
    }
    auto maybe_set = object->CreateDataProperty(context, property, new_field);
    // Setting a new value can fail in multiple scenarios. Bail out if it does.
    if (!maybe_set.IsJust() || !maybe_set.FromJust())
      return;
  } else {
    NOTREACHED();
  }
  info.GetReturnValue().Set(new_field);

  UMA_HISTOGRAM_TIMES("Extensions.ApiBindingGenerationTime", timer.Elapsed());
}

void ModuleSystem::SetLazyField(v8::Local<v8::Object> object,
                                const std::string& field,
                                const std::string& module_name,
                                const std::string& module_field) {
  SetLazyField(
      object, field, module_name, module_field, &ModuleSystem::LazyFieldGetter);
}

void ModuleSystem::SetLazyField(v8::Local<v8::Object> object,
                                const std::string& field,
                                const std::string& module_name,
                                const std::string& module_field,
                                v8::AccessorNameGetterCallback getter) {
  CHECK(field.size() < v8::String::kMaxLength);
  CHECK(module_name.size() < v8::String::kMaxLength);
  CHECK(module_field.size() < v8::String::kMaxLength);
  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Object> parameters = v8::Object::New(GetIsolate());
  v8::Local<v8::Context> context = context_->v8_context();
  // Since we reset the accessor here, we remove the record of having loaded the
  // module.
  loaded_modules_.erase(module_name);
  SetPrivateProperty(context, parameters, kModuleName,
              ToV8StringUnsafe(GetIsolate(), module_name.c_str()));
  SetPrivateProperty(context, parameters, kModuleField,
              ToV8StringUnsafe(GetIsolate(), module_field.c_str()));
  auto maybe = object->SetAccessor(
      context, ToV8StringUnsafe(GetIsolate(), field.c_str()), getter, NULL,
      parameters);
  CHECK(IsTrue(maybe));
}

void ModuleSystem::SetNativeLazyField(v8::Local<v8::Object> object,
                                      const std::string& field,
                                      const std::string& module_name,
                                      const std::string& module_field) {
  SetLazyField(object,
               field,
               module_name,
               module_field,
               &ModuleSystem::NativeLazyFieldGetter);
}

void ModuleSystem::OnNativeBindingCreated(
    const std::string& api_name,
    v8::Local<v8::Value> api_bridge_value) {
  DCHECK(!get_internal_api_.IsEmpty());
  v8::HandleScope scope(GetIsolate());
  if (source_map_->Contains(api_name)) {
    // We need to load the custom bindings and store them in our modules.
    // Storing them is important so that calls through CallModuleMethod() route
    // to the proper objects, if they share the same name as an API.
    v8::Local<v8::Value> modules;
    if (!GetPrivate(context()->v8_context()->Global(), kModulesField,
                    &modules) ||
        !modules->IsObject()) {
      NOTREACHED();
      return;
    }

    NativesEnabledScope enabled(this);
    v8::Local<v8::Value> exports =
        LoadModuleWithNativeAPIBridge(api_name, api_bridge_value);
    SetPrivateProperty(context()->v8_context(), modules.As<v8::Object>(),
                       gin::StringToSymbol(GetIsolate(), api_name), exports);
  }
}

void ModuleSystem::SetGetInternalAPIHook(
    v8::Local<v8::FunctionTemplate> get_internal_api) {
  DCHECK(get_internal_api_.IsEmpty());
  get_internal_api_.Set(GetIsolate(), get_internal_api);
}

void ModuleSystem::SetJSBindingUtilGetter(const JSBindingUtilGetter& getter) {
  DCHECK(js_binding_util_getter_.is_null());
  js_binding_util_getter_ = getter;
}

v8::Local<v8::Value> ModuleSystem::RunString(v8::Local<v8::String> code,
                                             v8::Local<v8::String> name) {
  return context_->RunScript(
      name, code,
      base::Bind(&ExceptionHandler::HandleUncaughtException,
                 base::Unretained(exception_handler_.get())),
      v8::ScriptCompiler::NoCacheReason::kNoCacheBecauseExtensionModule);
}

void ModuleSystem::RequireNative(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_EQ(1, args.Length());
  std::string native_name = *v8::String::Utf8Value(args.GetIsolate(), args[0]);
  v8::Local<v8::Object> object;
  if (RequireNativeFromString(native_name).ToLocal(&object))
    args.GetReturnValue().Set(object);
}

v8::MaybeLocal<v8::Object> ModuleSystem::RequireNativeFromString(
    const std::string& native_name) {
  if (natives_enabled_ == 0) {
    // HACK: if in test throw exception so that we can test the natives-disabled
    // logic; however, under normal circumstances, this is programmer error so
    // we could crash.
    if (exception_handler_) {
      GetIsolate()->ThrowException(
          ToV8StringUnsafe(GetIsolate(), "Natives disabled"));
      return v8::MaybeLocal<v8::Object>();
    }
    Fatal(context_, "Natives disabled for requireNative(" + native_name + ")");
    return v8::MaybeLocal<v8::Object>();
  }

  if (overridden_native_handlers_.count(native_name) > 0u) {
    v8::Local<v8::Value> value = RequireForJsInner(
        ToV8StringUnsafe(GetIsolate(), native_name.c_str()), true /* create */);
    if (value.IsEmpty() || !value->IsObject())
      return v8::MaybeLocal<v8::Object>();
    return value.As<v8::Object>();
  }

  auto i = native_handler_map_.find(native_name);
  if (i == native_handler_map_.end()) {
    Fatal(context_,
          "Couldn't find native for requireNative(" + native_name + ")");
    return v8::MaybeLocal<v8::Object>();
  }

  if (!i->second->IsInitialized())
    i->second->Initialize();

  return i->second->NewInstance();
}

void ModuleSystem::LoadScript(const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_EQ(1, args.Length());
  std::string module_name = *v8::String::Utf8Value(GetIsolate(), args[0]);

  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::String> source =
      source_map_->GetSource(GetIsolate(), module_name);
  if (source.IsEmpty())
    Fatal(context_, "No source for loadScript(" + module_name + ")");

  v8::Local<v8::String> v8_module_name;
  if (!ToV8String(GetIsolate(), module_name.c_str(), &v8_module_name))
    Warn(GetIsolate(), "module_name is too long");

  RunString(source, v8_module_name);
  args.GetReturnValue().Set(v8::Undefined(GetIsolate()));
}

v8::Local<v8::String> ModuleSystem::WrapSource(v8::Local<v8::String> source) {
  v8::EscapableHandleScope handle_scope(GetIsolate());
  // Keep in order with the arguments in RequireForJsInner.
  v8::Local<v8::String> left = ToV8StringUnsafe(
      GetIsolate(),
      "(function(require, requireNative, loadScript, exports, console, "
      "privates, apiBridge, bindingUtil, getInternalApi, $Array, $Function, "
      "$JSON, $Object, $RegExp, $String, $Error) {"
      "'use strict';");
  v8::Local<v8::String> right = ToV8StringUnsafe(GetIsolate(), "\n})");
  return handle_scope.Escape(v8::Local<v8::String>(v8::String::Concat(
      GetIsolate(), left, v8::String::Concat(GetIsolate(), source, right))));
}

void ModuleSystem::Private(const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_EQ(1, args.Length());
  if (!args[0]->IsObject() || args[0]->IsNull()) {
    GetIsolate()->ThrowException(
        v8::Exception::TypeError(ToV8StringUnsafe(GetIsolate(),
            args[0]->IsUndefined()
                ? "Method called without a valid receiver (this). "
                  "Did you forget to call .bind()?"
                : "Invalid invocation: receiver is not an object!")));
    return;
  }
  v8::Local<v8::Object> obj = args[0].As<v8::Object>();
  v8::Local<v8::Value> privates;
  if (!GetPrivate(obj, "privates", &privates) || !privates->IsObject()) {
    privates = v8::Object::New(args.GetIsolate());
    if (privates.IsEmpty()) {
      GetIsolate()->ThrowException(
          ToV8StringUnsafe(GetIsolate(), "Failed to create privates"));
      return;
    }
    v8::Maybe<bool> maybe =
        privates.As<v8::Object>()->SetPrototype(context()->v8_context(),
                                                v8::Null(args.GetIsolate()));
    CHECK(maybe.IsJust() && maybe.FromJust());
    SetPrivate(obj, "privates", privates);
  }
  args.GetReturnValue().Set(privates);
}

v8::Local<v8::Value> ModuleSystem::LoadModule(const std::string& module_name) {
  return LoadModuleWithNativeAPIBridge(module_name,
                                       v8::Undefined(GetIsolate()));
}

v8::Local<v8::Value> ModuleSystem::LoadModuleWithNativeAPIBridge(
    const std::string& module_name,
    v8::Local<v8::Value> api_bridge) {
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> v8_context = context()->v8_context();
  v8::Context::Scope context_scope(v8_context);

  v8::Local<v8::String> source =
      source_map_->GetSource(GetIsolate(), module_name);
  if (source.IsEmpty()) {
    Fatal(context_, "No source for require(" + module_name + ")");
    return v8::Undefined(GetIsolate());
  }
  v8::Local<v8::String> wrapped_source(WrapSource(source));
  v8::Local<v8::String> v8_module_name;
  if (!ToV8String(GetIsolate(), module_name.c_str(), &v8_module_name)) {
    NOTREACHED() << "module_name is too long";
    return v8::Undefined(GetIsolate());
  }
  // Modules are wrapped in (function(){...}) so they always return functions.
  v8::Local<v8::Value> func_as_value =
      RunString(wrapped_source, v8_module_name);
  if (func_as_value.IsEmpty() || func_as_value->IsUndefined()) {
    Fatal(context_, "Bad source for require(" + module_name + ")");
    return v8::Undefined(GetIsolate());
  }

  v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(func_as_value);

  v8::Local<v8::Object> exports = v8::Object::New(GetIsolate());

  v8::Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(
      GetIsolate(),
      &SetExportsProperty);
  tmpl->RemovePrototype();
  v8::Local<v8::String> v8_key;
  if (!v8_helpers::ToV8String(GetIsolate(), "$set", &v8_key)) {
    NOTREACHED();
    return v8::Undefined(GetIsolate());
  }

  v8::Local<v8::Function> function;
  if (!tmpl->GetFunction(v8_context).ToLocal(&function)) {
    NOTREACHED();
    return v8::Undefined(GetIsolate());
  }

  exports->DefineOwnProperty(v8_context, v8_key, function, v8::ReadOnly)
      .FromJust();

  v8::Local<v8::Object> natives(NewInstance());
  CHECK(!natives.IsEmpty());  // this can fail if v8 has issues

  v8::Local<v8::Value> get_internal_api;
  if (get_internal_api_.IsEmpty()) {
    get_internal_api = v8::Undefined(GetIsolate());
  } else {
    get_internal_api = get_internal_api_.Get(GetIsolate())
                           ->GetFunction(v8_context)
                           .ToLocalChecked();
  }

  v8::Local<v8::Value> binding_util;
  if (!js_binding_util_getter_.is_null()) {
    js_binding_util_getter_.Run(v8_context, &binding_util);
    if (binding_util.IsEmpty()) {
      // The NativeExtensionBindingsSystem was destroyed. This shouldn't happen,
      // but JS makes the impossible possible!
      NOTREACHED();
      return v8::Undefined(GetIsolate());
    }
  } else {
    binding_util = v8::Undefined(GetIsolate());
  }

  // These must match the argument order in WrapSource.
  v8::Local<v8::Value> args[] = {
      // CommonJS.
      GetPropertyUnsafe(v8_context, natives, "require",
                        v8::NewStringType::kInternalized),
      GetPropertyUnsafe(v8_context, natives, "requireNative",
                        v8::NewStringType::kInternalized),
      GetPropertyUnsafe(v8_context, natives, "loadScript",
                        v8::NewStringType::kInternalized),
      exports,
      // Libraries that we magically expose to every module.
      console::AsV8Object(GetIsolate()),
      GetPropertyUnsafe(v8_context, natives, "privates",
                        v8::NewStringType::kInternalized),
      api_bridge,        // exposed as apiBridge.
      binding_util,      // exposed as bindingUtil.
      get_internal_api,  // exposed as getInternalApi.
      // Each safe builtin. Keep in order with the arguments in WrapSource.
      context_->safe_builtins()->GetArray(),
      context_->safe_builtins()->GetFunction(),
      context_->safe_builtins()->GetJSON(),
      context_->safe_builtins()->GetObjekt(),
      context_->safe_builtins()->GetRegExp(),
      context_->safe_builtins()->GetString(),
      context_->safe_builtins()->GetError(),
  };
  {
    v8::TryCatch try_catch(GetIsolate());
    try_catch.SetCaptureMessage(true);
    context_->SafeCallFunction(func, base::size(args), args);
    if (try_catch.HasCaught()) {
      HandleException(try_catch);
      return v8::Undefined(GetIsolate());
    }
  }
  return handle_scope.Escape(exports);
}

void ModuleSystem::ClobberExistingNativeHandler(const std::string& name) {
  auto existing_handler = native_handler_map_.find(name);
  if (existing_handler != native_handler_map_.end()) {
    clobbered_native_handlers_.push_back(std::move(existing_handler->second));
    native_handler_map_.erase(existing_handler);
  }
}

v8::Local<v8::Function> ModuleSystem::GetModuleFunction(
    const std::string& module_name,
    const std::string& method_name) {
  v8::Local<v8::String> v8_module_name;
  v8::Local<v8::String> v8_method_name;
  if (!ToV8String(GetIsolate(), module_name.c_str(), &v8_module_name) ||
      !ToV8String(GetIsolate(), method_name.c_str(), &v8_method_name)) {
    return v8::Local<v8::Function>();
  }

  v8::Local<v8::Value> module;
  // Important: don't create the module if it doesn't exist. Doing so would
  // force a call into JS, which is something we want to avoid in case it has
  // been suspended. Additionally, we should only be calling module methods for
  // modules that have been instantiated.
  bool create = false;
  module = RequireForJsInner(v8_module_name, create);

  // RequireForJsInner() returns Undefined in the case of a module not being
  // loaded, since we don't create it here.
  if (!module.IsEmpty() && module->IsUndefined())
    return v8::Local<v8::Function>();

  if (module.IsEmpty() || !module->IsObject()) {
    Fatal(context_,
          "Failed to get module " + module_name + " to call " + method_name);
    return v8::Local<v8::Function>();
  }

  v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(module);
  v8::Local<v8::Value> value;
  if (!GetProperty(context()->v8_context(), object, v8_method_name, &value) ||
      !value->IsFunction()) {
    Fatal(context_, module_name + "." + method_name + " is not a function");
    return v8::Local<v8::Function>();
  }

  return v8::Local<v8::Function>::Cast(value);
}

}  // namespace extensions
