// 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/runtime_custom_bindings.h"

#include <stdint.h>

#include <memory>

#include "base/bind.h"
#include "base/values.h"
#include "content/public/child/v8_value_converter.h"
#include "content/public/renderer/render_frame.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/manifest.h"
#include "extensions/renderer/api_activity_logger.h"
#include "extensions/renderer/extension_frame_helper.h"
#include "extensions/renderer/script_context.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"

using content::V8ValueConverter;

namespace extensions {

RuntimeCustomBindings::RuntimeCustomBindings(ScriptContext* context)
    : ObjectBackedNativeHandler(context) {
  RouteFunction(
      "GetManifest",
      base::Bind(&RuntimeCustomBindings::GetManifest, base::Unretained(this)));
  RouteFunction("OpenChannelToExtension", "runtime.connect",
                base::Bind(&RuntimeCustomBindings::OpenChannelToExtension,
                           base::Unretained(this)));
  RouteFunction("OpenChannelToNativeApp", "runtime.connectNative",
                base::Bind(&RuntimeCustomBindings::OpenChannelToNativeApp,
                           base::Unretained(this)));
  RouteFunction("GetExtensionViews",
                base::Bind(&RuntimeCustomBindings::GetExtensionViews,
                           base::Unretained(this)));
}

RuntimeCustomBindings::~RuntimeCustomBindings() {
}

void RuntimeCustomBindings::OpenChannelToExtension(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  // Get the current RenderFrame so that we can send a routed IPC message from
  // the correct source.
  content::RenderFrame* renderframe = context()->GetRenderFrame();
  if (!renderframe)
    return;

  // The Javascript code should validate/fill the arguments.
  CHECK_EQ(args.Length(), 3);
  CHECK(args[0]->IsString() && args[1]->IsString() && args[2]->IsBoolean());

  ExtensionMsg_ExternalConnectionInfo info;

  // For messaging APIs, hosted apps should be considered a web page so hide
  // its extension ID.
  const Extension* extension = context()->extension();
  if (extension && !extension->is_hosted_app())
    info.source_id = extension->id();

  info.target_id = *v8::String::Utf8Value(args[0]);
  info.source_url = context()->url();
  std::string channel_name = *v8::String::Utf8Value(args[1]);
  bool include_tls_channel_id =
      args.Length() > 2 ? args[2]->BooleanValue() : false;
  int port_id = -1;
  renderframe->Send(new ExtensionHostMsg_OpenChannelToExtension(
      renderframe->GetRoutingID(), info, channel_name, include_tls_channel_id,
      &port_id));
  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
}

void RuntimeCustomBindings::OpenChannelToNativeApp(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  // Verify that the extension has permission to use native messaging.
  Feature::Availability availability =
      FeatureProvider::GetPermissionFeatures()
          ->GetFeature("nativeMessaging")
          ->IsAvailableToContext(context()->extension(),
                                 context()->context_type(), context()->url());
  if (!availability.is_available())
    return;

  content::RenderFrame* render_frame = context()->GetRenderFrame();
  if (!render_frame)
    return;

  // The Javascript code should validate/fill the arguments.
  CHECK(args.Length() >= 2 && args[0]->IsString() && args[1]->IsString());

  std::string extension_id = *v8::String::Utf8Value(args[0]);
  std::string native_app_name = *v8::String::Utf8Value(args[1]);

  int port_id = -1;
  render_frame->Send(new ExtensionHostMsg_OpenChannelToNativeApp(
      render_frame->GetRoutingID(), extension_id, native_app_name, &port_id));
  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
}

void RuntimeCustomBindings::GetManifest(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK(context()->extension());

  std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create());
  args.GetReturnValue().Set(converter->ToV8Value(
      context()->extension()->manifest()->value(), context()->v8_context()));
}

void RuntimeCustomBindings::GetExtensionViews(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  if (args.Length() != 2)
    return;

  if (!args[0]->IsInt32() || !args[1]->IsString())
    return;

  // |browser_window_id| == extension_misc::kUnknownWindowId means getting
  // all views for the current extension.
  int browser_window_id = args[0]->Int32Value();

  std::string view_type_string =
      base::ToUpperASCII(*v8::String::Utf8Value(args[1]));
  // |view_type| == VIEW_TYPE_INVALID means getting any type of
  // views.
  ViewType view_type = VIEW_TYPE_INVALID;
  if (view_type_string == kViewTypeBackgroundPage) {
    view_type = VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
  } else if (view_type_string == kViewTypeTabContents) {
    view_type = VIEW_TYPE_TAB_CONTENTS;
  } else if (view_type_string == kViewTypePopup) {
    view_type = VIEW_TYPE_EXTENSION_POPUP;
  } else if (view_type_string == kViewTypeExtensionDialog) {
    view_type = VIEW_TYPE_EXTENSION_DIALOG;
  } else if (view_type_string == kViewTypeAppWindow) {
    view_type = VIEW_TYPE_APP_WINDOW;
  } else if (view_type_string == kViewTypeLauncherPage) {
    view_type = VIEW_TYPE_LAUNCHER_PAGE;
  } else if (view_type_string == kViewTypePanel) {
    view_type = VIEW_TYPE_PANEL;
  } else if (view_type_string != kViewTypeAll) {
    return;
  }

  std::string extension_id = context()->GetExtensionID();
  if (extension_id.empty())
    return;

  std::vector<content::RenderFrame*> frames =
      ExtensionFrameHelper::GetExtensionFrames(extension_id, browser_window_id,
                                               view_type);
  v8::Local<v8::Context> v8_context = args.GetIsolate()->GetCurrentContext();
  v8::Local<v8::Array> v8_views = v8::Array::New(args.GetIsolate());
  int v8_index = 0;
  for (content::RenderFrame* frame : frames) {
    // We filter out iframes here. GetExtensionViews should only return the
    // main views, not any subframes. (Returning subframes can cause broken
    // behavior by treating an app window's iframe as its main frame, and maybe
    // other nastiness).
    if (frame->GetWebFrame()->top() != frame->GetWebFrame())
      continue;

    v8::Local<v8::Context> context =
        frame->GetWebFrame()->mainWorldScriptContext();
    if (!context.IsEmpty()) {
      v8::Local<v8::Value> window = context->Global();
      DCHECK(!window.IsEmpty());
      v8::Maybe<bool> maybe =
        v8_views->CreateDataProperty(v8_context, v8_index++, window);
      DCHECK(maybe.IsJust() && maybe.FromJust());
    }
  }

  args.GetReturnValue().Set(v8_views);
}

}  // namespace extensions
