// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/script/mozjs-45/wrapper_private.h"

#include "base/hash_tables.h"
#include "cobalt/script/mozjs-45/mozjs_global_environment.h"
#include "cobalt/script/mozjs-45/proxy_handler.h"
#include "cobalt/script/mozjs-45/referenced_object_map.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
#include "third_party/mozjs-45/js/src/jsfun.h"
#include "third_party/mozjs-45/js/src/proxy/Proxy.h"
#include "third_party/mozjs-45/js/src/vm/NativeObject.h"

namespace cobalt {
namespace script {
namespace mozjs {

void Tracer::Trace(Wrappable* wrappable) {
  // Clearly, a null wrappable could not possibly reference any other
  // wrappables.
  if (!wrappable) {
    return;
  }

  // Unfortunately, |JSTracer| will only supply us with a |JSRuntime|,
  // rather than a |JSContext|. Fortunately, Cobalt will only create one
  // global environment per runtime, so we can still safely get back to our
  // context, and thus our global environment.
  JSContext* context = NULL;
  JS_ContextIterator(js_tracer_->runtime(), &context);
  DCHECK(context);
  MozjsGlobalEnvironment* global_environment =
      MozjsGlobalEnvironment::GetFromContext(context);
  DCHECK(global_environment);

  // Clearly, if we have already visited this wrappable during the current
  // tracing session, there is no need to visit it again. We rely on
  // |JS_SetGCCallback| in the |MozjsEngine| to properly manage clearing
  // |visited_wrappables_| in between GC sessions.
  base::hash_set<Wrappable*>* visited_wrappables =
      global_environment->visited_wrappables();
  DCHECK(visited_wrappables);
  if (!visited_wrappables->insert(wrappable).second) {
    return;
  }

  // There are now two cases left to handle. Since we cannot create the
  // wrapper while tracing due to internal SpiderMonkey restrictions, we will
  // instead directly call |TraceMembers| here if the wrapper does not exist.
  // In the case where the wrapper already does exist, we will pass the
  // wrapper to |JS_CallObjectTracer|, and rely on SpiderMonkey to begin
  // another |WrapperPrivate::Trace| on that wrapper.
  WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
  if (!wrapper_factory->HasWrapperProxy(wrappable)) {
    frontier_.push_back(wrappable);
  } else {
    JSObject* proxy_object = wrapper_factory->GetWrapperProxy(wrappable);
    JSObject* target = js::GetProxyTargetObject(proxy_object);
    WrapperPrivate* wrapper_private =
        static_cast<WrapperPrivate*>(JS_GetPrivate(target));
    DCHECK(wrapper_private->context_ == context);
    DCHECK(wrapper_private->wrapper_proxy_);
    JS_CallObjectTracer(js_tracer_, &wrapper_private->wrapper_proxy_,
                        "WrapperPrivate::TraceWrappable");
  }

  DCHECK(JS_ContextIterator(js_tracer_->runtime(), &context) == NULL);
}

void Tracer::TraceFrom(Wrappable* wrappable) {
  DCHECK(frontier_.empty());
  frontier_.push_back(wrappable);
  while (!frontier_.empty()) {
    Wrappable* wrappable = frontier_.back();
    frontier_.pop_back();
    wrappable->TraceMembers(this);
  }
}

Wrappable* WrapperPrivate::GetOpaqueRoot() const {
  if (!get_opaque_root_function_.is_null()) {
    return get_opaque_root_function_.Run(wrappable_);
  }
  return NULL;
}

void WrapperPrivate::GetReachableWrappables(
    std::vector<Wrappable*>* reachable) {
  if (!get_reachable_wrappables_function_.is_null()) {
    return get_reachable_wrappables_function_.Run(wrappable_, reachable);
  }
}

bool WrapperPrivate::ShouldKeepWrapperAliveIfReachable() {
  const ProxyHandler* proxy_handler =
      base::polymorphic_downcast<const ProxyHandler*>(
          js::GetProxyHandler(wrapper_proxy_));

  DCHECK(proxy_handler);
  return proxy_handler->has_custom_property() ||
         wrappable_->ShouldKeepWrapperAlive();
}

// static
void WrapperPrivate::AddPrivateData(
    JSContext* context, JS::HandleObject wrapper_proxy,
    const scoped_refptr<Wrappable>& wrappable,
    const GetOpaqueRootFunction& get_opaque_root_function,
    const GetReachableWrappablesFunction& get_reachable_wrappables_function) {
  DCHECK(js::IsProxy(wrapper_proxy));
  WrapperPrivate* private_data = new WrapperPrivate(
      context, wrappable, wrapper_proxy, get_opaque_root_function,
      get_reachable_wrappables_function);
  JS::RootedObject target_object(context,
                                 js::GetProxyTargetObject(wrapper_proxy));
  JS_SetPrivate(target_object, private_data);
  DCHECK_EQ(JS_GetPrivate(target_object), private_data);
}

// static
bool WrapperPrivate::HasWrapperPrivate(JSContext* context,
                                       JS::HandleObject object) {
  if (js::IsProxy(object)) {
    JS::RootedObject target_object(context, js::GetProxyTargetObject(object));
    return WrapperPrivate::HasWrapperPrivate(context, target_object);
  }

  DCHECK(object->isNative());
  return object->as<js::NativeObject>().hasPrivate();
}

// static
WrapperPrivate* WrapperPrivate::GetFromWrappable(
    const scoped_refptr<Wrappable>& wrappable, JSContext* context,
    WrapperFactory* wrapper_factory) {
  JS::RootedObject wrapper_proxy(context,
                                 wrapper_factory->GetWrapperProxy(wrappable));
  WrapperPrivate* private_data = GetFromProxyObject(context, wrapper_proxy);
  DCHECK(private_data);
  DCHECK_EQ(private_data->wrappable_, wrappable);
  return private_data;
}

// static
WrapperPrivate* WrapperPrivate::GetFromWrapperObject(JS::HandleObject wrapper) {
  DCHECK(!js::IsProxy(wrapper));
  WrapperPrivate* private_data =
      static_cast<WrapperPrivate*>(JS_GetPrivate(wrapper));
  DCHECK(private_data);
  return private_data;
}

// static
WrapperPrivate* WrapperPrivate::GetFromProxyObject(
    JSContext* context, JS::HandleObject proxy_object) {
  DCHECK(js::IsProxy(proxy_object));
  JS::RootedObject target(context, js::GetProxyTargetObject(proxy_object));
  return GetFromWrapperObject(target);
}

// static
WrapperPrivate* WrapperPrivate::GetFromObject(JSContext* context,
                                              JS::HandleObject object) {
  if (js::IsProxy(object)) {
    return GetFromProxyObject(context, object);
  } else {
    return GetFromWrapperObject(object);
  }
}

// static
void WrapperPrivate::Finalizer(JSFreeOp* /* free_op */, JSObject* object) {
  WrapperPrivate* wrapper_private =
      reinterpret_cast<WrapperPrivate*>(JS_GetPrivate(object));
  DCHECK(wrapper_private);
  delete wrapper_private;
}

// static
void WrapperPrivate::Trace(JSTracer* trace, JSObject* object) {
  WrapperPrivate* wrapper_private =
      reinterpret_cast<WrapperPrivate*>(JS_GetPrivate(object));
  // Verify that this trace function is called for the object (rather than the
  // proxy object).
  DCHECK(!js::IsProxy(object));

  // The GC could run on this object before we've had a chance to set its
  // private data, so we must handle the case where JS_GetPrivate returns NULL.
  if (wrapper_private) {
    // Verify that WrapperPrivate::wrapper_proxy_'s target object is this
    // object.
    DCHECK_EQ(object,
              js::GetProxyTargetObject(wrapper_private->wrapper_proxy_));

    // The wrapper's proxy object will keep the wrapper object alive, but the
    // reverse is not true, so we must trace it explicitly.
    JS_CallObjectTracer(trace, &wrapper_private->wrapper_proxy_,
                        "WrapperPrivate::Trace");

    MozjsGlobalEnvironment* global_environment =
        MozjsGlobalEnvironment::GetFromContext(wrapper_private->context_);
    intptr_t key = ReferencedObjectMap::GetKeyForWrappable(
        wrapper_private->wrappable_.get());
    global_environment->referenced_objects()->TraceReferencedObjects(trace,
                                                                     key);
    Tracer tracer(trace);
    tracer.TraceFrom(wrapper_private->wrappable_);
  }
}

WrapperPrivate::WrapperPrivate(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable,
    JS::HandleObject wrapper_proxy,
    const GetOpaqueRootFunction& get_opaque_root_function,
    const GetReachableWrappablesFunction& get_reachable_wrappables_function)
    : context_(context),
      wrappable_(wrappable),
      wrapper_proxy_(wrapper_proxy),
      get_opaque_root_function_(get_opaque_root_function),
      get_reachable_wrappables_function_(get_reachable_wrappables_function) {
  DCHECK(js::IsProxy(wrapper_proxy));
  if (!get_opaque_root_function_.is_null() ||
      !get_reachable_wrappables_function_.is_null()) {
    MozjsGlobalEnvironment* global_environment =
        MozjsGlobalEnvironment::GetFromContext(context_);
    global_environment->opaque_root_tracker()->AddObjectWithOpaqueRoot(this);
  }
}

WrapperPrivate::~WrapperPrivate() {
  if (!get_opaque_root_function_.is_null() ||
      !get_reachable_wrappables_function_.is_null()) {
    MozjsGlobalEnvironment* global_environment =
        MozjsGlobalEnvironment::GetFromContext(context_);
    global_environment->opaque_root_tracker()->RemoveObjectWithOpaqueRoot(this);
  }
  wrapper_proxy_ = NULL;
}

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt
