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

#include "base/auto_reset.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/gin_java_bridge_messages.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/java/gin_java_bridge_object.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"

namespace content {

GinJavaBridgeDispatcher::GinJavaBridgeDispatcher(RenderFrame* render_frame)
    : RenderFrameObserver(render_frame),
      inside_did_clear_window_object_(false) {
}

GinJavaBridgeDispatcher::~GinJavaBridgeDispatcher() {
}

bool GinJavaBridgeDispatcher::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(GinJavaBridgeDispatcher, msg)
    IPC_MESSAGE_HANDLER(GinJavaBridgeMsg_AddNamedObject, OnAddNamedObject)
    IPC_MESSAGE_HANDLER(GinJavaBridgeMsg_RemoveNamedObject, OnRemoveNamedObject)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void GinJavaBridgeDispatcher::DidClearWindowObject() {
  // Accessing window object when adding properties to it may trigger
  // a nested call to DidClearWindowObject.
  if (inside_did_clear_window_object_)
    return;
  base::AutoReset<bool> flag_entry(&inside_did_clear_window_object_, true);
  for (NamedObjectMap::const_iterator iter = named_objects_.begin();
       iter != named_objects_.end(); ++iter) {
    // Always create a new GinJavaBridgeObject, so we don't pull any of the V8
    // wrapper's custom properties into the context of the page we have
    // navigated to. The old GinJavaBridgeObject will be automatically
    // deleted after its wrapper will be collected.
    // On the browser side, we ignore wrapper deletion events for named objects,
    // as they are only removed upon embedder's request (RemoveNamedObject).
    if (objects_.Lookup(iter->second))
      objects_.Remove(iter->second);
    GinJavaBridgeObject* object = GinJavaBridgeObject::InjectNamed(
        render_frame()->GetWebFrame(), AsWeakPtr(), iter->first, iter->second);
    if (object) {
      objects_.AddWithID(object, iter->second);
    } else {
      // Inform the host about wrapper creation failure.
      render_frame()->Send(new GinJavaBridgeHostMsg_ObjectWrapperDeleted(
          routing_id(), iter->second));
    }
  }
}

void GinJavaBridgeDispatcher::OnAddNamedObject(
    const std::string& name,
    ObjectID object_id) {
  // Added objects only become available after page reload, so here they
  // are only added into the internal map.
  named_objects_.insert(std::make_pair(name, object_id));
}

void GinJavaBridgeDispatcher::OnRemoveNamedObject(const std::string& name) {
  // Removal becomes in effect on next reload. We simply removing the entry
  // from the map here.
  NamedObjectMap::iterator iter = named_objects_.find(name);
  DCHECK(iter != named_objects_.end());
  named_objects_.erase(iter);
}

void GinJavaBridgeDispatcher::GetJavaMethods(
    ObjectID object_id,
    std::set<std::string>* methods) {
  render_frame()->Send(new GinJavaBridgeHostMsg_GetMethods(
      routing_id(), object_id, methods));
}

bool GinJavaBridgeDispatcher::HasJavaMethod(ObjectID object_id,
                                            const std::string& method_name) {
  bool result;
  render_frame()->Send(new GinJavaBridgeHostMsg_HasMethod(
      routing_id(), object_id, method_name, &result));
  return result;
}

std::unique_ptr<base::Value> GinJavaBridgeDispatcher::InvokeJavaMethod(
    ObjectID object_id,
    const std::string& method_name,
    const base::ListValue& arguments,
    GinJavaBridgeError* error) {
  base::ListValue result_wrapper;
  render_frame()->Send(
      new GinJavaBridgeHostMsg_InvokeMethod(routing_id(),
                                            object_id,
                                            method_name,
                                            arguments,
                                            &result_wrapper,
                                            error));
  base::Value* result;
  if (result_wrapper.Get(0, &result)) {
    return std::unique_ptr<base::Value>(result->DeepCopy());
  } else {
    return std::unique_ptr<base::Value>();
  }
}

GinJavaBridgeObject* GinJavaBridgeDispatcher::GetObject(ObjectID object_id) {
  GinJavaBridgeObject* result = objects_.Lookup(object_id);
  if (!result) {
    result = GinJavaBridgeObject::InjectAnonymous(AsWeakPtr(), object_id);
    if (result)
      objects_.AddWithID(result, object_id);
  }
  return result;
}

void GinJavaBridgeDispatcher::OnGinJavaBridgeObjectDeleted(
    GinJavaBridgeObject* object) {
  int object_id = object->object_id();
  // Ignore cleaning up of old object wrappers.
  if (objects_.Lookup(object_id) != object) return;
  objects_.Remove(object_id);
  render_frame()->Send(
      new GinJavaBridgeHostMsg_ObjectWrapperDeleted(routing_id(), object_id));
}

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

}  // namespace content
