// 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 "content/renderer/mojo_bindings_controller.h"

#include "base/memory/ptr_util.h"
#include "content/common/view_messages.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "content/renderer/mojo_context_state.h"
#include "gin/per_context_data.h"
#include "third_party/WebKit/public/web/WebContextFeatures.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "v8/include/v8.h"

namespace content {

namespace {

const char kMojoContextStateKey[] = "MojoContextState";

struct MojoContextStateData : public base::SupportsUserData::Data {
  std::unique_ptr<MojoContextState> state;
};

}  // namespace

MojoBindingsController::MojoBindingsController(RenderFrame* render_frame,
                                               MojoBindingsType bindings_type)
    : RenderFrameObserver(render_frame),
      RenderFrameObserverTracker<MojoBindingsController>(render_frame),
      bindings_type_(bindings_type) {}

MojoBindingsController::~MojoBindingsController() {
}

void MojoBindingsController::CreateContextState() {
  v8::HandleScope handle_scope(blink::MainThreadIsolate());
  blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
  v8::Local<v8::Context> context = frame->MainWorldScriptContext();
  gin::PerContextData* context_data = gin::PerContextData::From(context);
  auto data = base::MakeUnique<MojoContextStateData>();
  data->state.reset(new MojoContextState(frame, context, bindings_type_));
  context_data->SetUserData(kMojoContextStateKey, std::move(data));
}

void MojoBindingsController::DestroyContextState(
    v8::Local<v8::Context> context) {
  gin::PerContextData* context_data = gin::PerContextData::From(context);
  if (!context_data)
    return;
  context_data->RemoveUserData(kMojoContextStateKey);
}

MojoContextState* MojoBindingsController::GetContextState() {
  v8::HandleScope handle_scope(blink::MainThreadIsolate());
  v8::Local<v8::Context> context =
      render_frame()->GetWebFrame()->MainWorldScriptContext();
  gin::PerContextData* context_data = gin::PerContextData::From(context);
  if (!context_data)
    return NULL;
  MojoContextStateData* context_state = static_cast<MojoContextStateData*>(
      context_data->GetUserData(kMojoContextStateKey));
  return context_state ? context_state->state.get() : NULL;
}

void MojoBindingsController::DidCreateScriptContext(
    v8::Local<v8::Context> context,
    int world_id) {
  // NOTE: Layout tests already get this turned on by the RuntimeEnabled feature
  // setting. We avoid manually installing them here for layout tests, because
  // some layout tests (namely at
  // least virtual/stable/webexposed/global-interface-listing.html) may be run
  // with such features explicitly disabled. We do not want to unconditionally
  // install Mojo bindings in such environments.
  //
  // We also only allow these bindings to be installed when creating the main
  // world context.
  if (bindings_type_ != MojoBindingsType::FOR_LAYOUT_TESTS && world_id == 0)
    blink::WebContextFeatures::EnableMojoJS(context, true);
}

void MojoBindingsController::WillReleaseScriptContext(
    v8::Local<v8::Context> context,
    int world_id) {
  DestroyContextState(context);
}

void MojoBindingsController::RunScriptsAtDocumentStart() {
  CreateContextState();
}

void MojoBindingsController::RunScriptsAtDocumentReady() {
  v8::HandleScope handle_scope(blink::MainThreadIsolate());
  MojoContextState* state = GetContextState();
  if (state)
    state->Run();
}

void MojoBindingsController::DidClearWindowObject() {
  // NOTE: this function may be called early on twice. From the constructor
  // mainWorldScriptContext() may trigger this to be called. If we are created
  // before the page is loaded (which is very likely), then on first load this
  // is called. In the case of the latter we may have already supplied the
  // handle to the context state so that if we destroy now the handle is
  // lost. If this is the result of the first load then the contextstate should
  // be empty and we don't need to destroy it.
  MojoContextState* state = GetContextState();
  if (state && !state->module_added())
    return;

  v8::HandleScope handle_scope(blink::MainThreadIsolate());
  DestroyContextState(render_frame()->GetWebFrame()->MainWorldScriptContext());
}

void MojoBindingsController::OnDestruct() {
  delete this;
}

}  // namespace content
