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

#include <algorithm>
#include <utility>

#include "base/lazy_instance.h"
#include "base/stringprintf.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/embedded_resources.h"
#include "cobalt/script/mozjs-45/mozjs_exception_state.h"
#include "cobalt/script/mozjs-45/mozjs_script_value_factory.h"
#include "cobalt/script/mozjs-45/mozjs_source_code.h"
#include "cobalt/script/mozjs-45/mozjs_wrapper_handle.h"
#include "cobalt/script/mozjs-45/proxy_handler.h"
#include "cobalt/script/mozjs-45/referenced_object_map.h"
#include "cobalt/script/mozjs-45/util/exception_helpers.h"
#include "nb/memory_scope.h"
#include "third_party/mozjs-45/js/public/Initialization.h"
#include "third_party/mozjs-45/js/src/jsfriendapi.h"
#include "third_party/mozjs-45/js/src/jsfun.h"
#include "third_party/mozjs-45/js/src/jsobj.h"

// A note on CompartmentOptions and Principals.
// These concepts are an integral part of Gecko's security implementation, but
// we don't need to be concerned with this for Cobalt.
//
// Compartments are separate regions of memory. Each global object has a
// separate compartment. Since Cobalt will use a different JSRuntime for each
// thread and each global object cannot access another directly anyways, this
// shouldn't be an issue even in our development workflow.
// If we support multiple windows in some form, a cross-compartment wrapper is
// needed to access another global object. If they are same-origin this is
// simpler.
// Principals (or Security principals) are used to determine the security
// relationship between two compartments. Since Cobalt does not have multiple
// global objects there is no need to define Security principals. Even so,
// it we'd likely want to implement such a security policy in an engine
// independent way anyways.
// See https://developer.mozilla.org/en-US/docs/Mozilla/Gecko/Script_security

namespace cobalt {
namespace script {
namespace mozjs {
namespace {

// Class definition for global object with no bindings.
JSClass simple_global_class = {"global", JSCLASS_GLOBAL_FLAGS,
                               NULL,     NULL,
                               NULL,     NULL,
                               NULL,     NULL,
                               NULL,     NULL,
                               NULL,     NULL,
                               NULL,     JS_GlobalObjectTraceHook};

// 8192 is the recommended default value.
const uint32_t kStackChunkSize = 8192;

// This is the default in the spidermonkey shell.
const uint32_t kMaxCodeCacheBytes = 16 * 1024 * 1024;

// DOM proxies have an extra slot for the expando object at index
// kJSProxySlotExpando.
// The expando object is a plain JSObject whose properties correspond to
// "expandos" (custom properties set by the script author).
// The exact value stored in the kJSProxySlotExpando slot depends on whether
// the interface is annotated with the [OverrideBuiltins] extended attribute.
const uint32_t kJSProxySlotExpando = 0;

// The DOMProxyShadowsCheck function will be called to check if the property for
// id should be gotten from the prototype, or if there is an own property that
// shadows it.
js::DOMProxyShadowsResult DOMProxyShadowsCheck(JSContext* context,
                                               JS::HandleObject proxy,
                                               JS::HandleId id) {
  DCHECK(IsProxy(proxy));
  JS::Value value = js::GetProxyExtra(proxy, kJSProxySlotExpando);
  DCHECK(value.isUndefined() || value.isObject());

  // [OverrideBuiltins] extended attribute is not supported.
  NOTIMPLEMENTED();

  // If DoesntShadow is returned then the slot at listBaseExpandoSlot should
  // either be undefined or point to an expando object that would contain the
  // own property.
  return js::DoesntShadow;
}

class MozjsStubHandler : public ProxyHandler {
 public:
  MozjsStubHandler()
      : ProxyHandler(indexed_property_hooks, named_property_hooks) {}

 private:
  static NamedPropertyHooks named_property_hooks;
  static IndexedPropertyHooks indexed_property_hooks;
};

ProxyHandler::NamedPropertyHooks MozjsStubHandler::named_property_hooks = {
    NULL, NULL, NULL, NULL, NULL,
};
ProxyHandler::IndexedPropertyHooks MozjsStubHandler::indexed_property_hooks = {
    NULL, NULL, NULL, NULL, NULL,
};

static base::LazyInstance<MozjsStubHandler> proxy_handler;
}  // namespace

MozjsGlobalEnvironment::MozjsGlobalEnvironment(
    JSRuntime* runtime, const JavaScriptEngine::Options& options)
    : context_(NULL),
      garbage_collection_count_(0),
      cached_interface_data_deleter_(&cached_interface_data_),
      context_destructor_(&context_),
      environment_settings_(NULL),
      last_error_message_(NULL),
      eval_enabled_(false) {
  TRACK_MEMORY_SCOPE("Javascript");
  context_ = JS_NewContext(runtime, kStackChunkSize);
  DCHECK(context_);
  // Set a pointer to this class inside the JSContext.
  JS_SetContextPrivate(context_, this);

  JS_SetGCParameterForThread(context_, JSGC_MAX_CODE_CACHE_BYTES,
                             kMaxCodeCacheBytes);

  wrapper_factory_.reset(new WrapperFactory(context_));
  script_value_factory_.reset(new MozjsScriptValueFactory(this));
  referenced_objects_.reset(new ReferencedObjectMap(context_));

  JS_AddExtraGCRootsTracer(runtime, TraceFunction, this);
}

MozjsGlobalEnvironment::~MozjsGlobalEnvironment() {
  DCHECK(thread_checker_.CalledOnValidThread());
  JS_RemoveExtraGCRootsTracer(JS_GetRuntime(context_), TraceFunction, this);
}

void MozjsGlobalEnvironment::CreateGlobalObject() {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!global_object_proxy_);

  // The global object is automatically rooted unless the
  // JSOPTION_UNROOTED_GLOBAL option is set.
  JSAutoRequest auto_request(context_);

  // NULL JSPrincipals and default JS::CompartmentOptions. See the comment
  // above for rationale.
  JS::RootedObject global_object(
      context_, JS_NewGlobalObject(context_, &simple_global_class, NULL,
                                   JS::FireOnNewGlobalHook));
  DCHECK(global_object);

  // Initialize standard JS constructors prototypes and top-level functions such
  // as Object, isNan, etc.
  JSAutoCompartment auto_compartment(context_, global_object);
  bool success = JS_InitStandardClasses(context_, global_object);
  DCHECK(success);

  JS::RootedObject proxy(
      context_, ProxyHandler::NewProxy(context_, proxy_handler.Pointer(),
                                       global_object, NULL));
  global_object_proxy_ = proxy;

  EvaluateAutomatics();
}

bool MozjsGlobalEnvironment::EvaluateScript(
    const scoped_refptr<SourceCode>& source_code,
    std::string* out_result_utf8) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK(thread_checker_.CalledOnValidThread());

  JSAutoRequest auto_request(context_);
  JSAutoCompartment auto_compartment(context_, global_object_proxy_);
  JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
  JS::RootedValue result_value(context_);

  std::string error_message;
  last_error_message_ = &error_message;

  bool success = EvaluateScriptInternal(source_code, &result_value);
  if (out_result_utf8) {
    if (success) {
      MozjsExceptionState exception_state(context_);
      FromJSValue(context_, result_value, kNoConversionFlags, &exception_state,
                  out_result_utf8);
    } else if (last_error_message_) {
      *out_result_utf8 = *last_error_message_;
    } else {
      DLOG(ERROR) << "Script execution failed.";
    }
  }
  last_error_message_ = NULL;
  JS_RestoreExceptionState(context_, previous_exception_state);
  return success;
}

bool MozjsGlobalEnvironment::EvaluateScript(
    const scoped_refptr<SourceCode>& source_code,
    const scoped_refptr<Wrappable>& owning_object,
    base::optional<OpaqueHandleHolder::Reference>* out_opaque_handle) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK(thread_checker_.CalledOnValidThread());
  JSAutoRequest auto_request(context_);
  JSAutoCompartment auto_compartment(context_, global_object_proxy_);
  JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
  JS::RootedValue result_value(context_);
  bool success = EvaluateScriptInternal(source_code, &result_value);
  if (success && out_opaque_handle) {
    JS::RootedObject js_object(context_);
    JS_ValueToObject(context_, result_value, &js_object);
    MozjsObjectHandleHolder mozjs_object_holder(js_object, context_,
                                                wrapper_factory());
    out_opaque_handle->emplace(owning_object.get(), mozjs_object_holder);
  }
  JS_RestoreExceptionState(context_, previous_exception_state);
  return success;
}

bool MozjsGlobalEnvironment::EvaluateScriptInternal(
    const scoped_refptr<SourceCode>& source_code,
    JS::MutableHandleValue out_result) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(global_object_proxy_);
  MozjsSourceCode* mozjs_source_code =
      base::polymorphic_downcast<MozjsSourceCode*>(source_code.get());

  const std::string& script = mozjs_source_code->source_utf8();
  const base::SourceLocation location = mozjs_source_code->location();

  JS::RootedObject global_object(
      context_, js::GetProxyTargetObject(global_object_proxy_));

  size_t length = script.size();
  char16_t* inflated_buffer =
      UTF8CharsToNewTwoByteCharsZ(
          context_, JS::UTF8Chars(script.c_str(), length), &length)
          .get();

  bool success = false;
  if (inflated_buffer) {
    JS::CompileOptions options(context_);
    options.setFileAndLine(location.file_path.c_str(), location.line_number);
    success =
        JS::Evaluate(context_, options, inflated_buffer, length, out_result);
    js_free(inflated_buffer);
  } else {
    DLOG(ERROR) << "Malformed UTF-8 script.";
  }

  return success;
}

void MozjsGlobalEnvironment::EvaluateEmbeddedScript(
    const unsigned char* data, size_t size, const char* filename) {
  TRACK_MEMORY_SCOPE("Javascript");
  std::string source(reinterpret_cast<const char*>(data), size);
  scoped_refptr<SourceCode> source_code =
      new MozjsSourceCode(source, base::SourceLocation(filename, 1, 1));
  std::string result;
  bool success = EvaluateScript(source_code, &result);
  if (!success) {
    DLOG(FATAL) << result;
  }
}

std::vector<StackFrame> MozjsGlobalEnvironment::GetStackTrace(int max_frames) {
  DCHECK(thread_checker_.CalledOnValidThread());
  return util::GetStackTrace(context_, max_frames);
}

void MozjsGlobalEnvironment::PreventGarbageCollection(
    const scoped_refptr<Wrappable>& wrappable) {
  DCHECK(thread_checker_.CalledOnValidThread());
  JSAutoRequest auto_request(context_);
  JSAutoCompartment auto_compartment(context_, global_object_proxy_);
  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromWrappable(wrappable, context_, wrapper_factory());
  JS::RootedObject proxy(context_, wrapper_private->js_object_proxy());
  kept_alive_objects_.insert(CachedWrapperMultiMap::value_type(
      wrappable.get(), JS::Heap<JSObject*>(proxy)));
}

void MozjsGlobalEnvironment::AllowGarbageCollection(
    const scoped_refptr<Wrappable>& wrappable) {
  TRACK_MEMORY_SCOPE("Javascript");
  DCHECK(thread_checker_.CalledOnValidThread());
  CachedWrapperMultiMap::iterator it =
      kept_alive_objects_.find(wrappable.get());
  DCHECK(it != kept_alive_objects_.end());
  if (it != kept_alive_objects_.end()) {
    kept_alive_objects_.erase(it);
  }
}

void MozjsGlobalEnvironment::DisableEval(const std::string& message) {
  DCHECK(thread_checker_.CalledOnValidThread());
  eval_disabled_message_.emplace(message);
  eval_enabled_ = false;
}

void MozjsGlobalEnvironment::EnableEval() {
  DCHECK(thread_checker_.CalledOnValidThread());
  eval_disabled_message_ = base::nullopt;
  eval_enabled_ = true;
}

void MozjsGlobalEnvironment::DisableJit() {
  DCHECK(thread_checker_.CalledOnValidThread());
  JS::RuntimeOptionsRef(context_)
      .setBaseline(false)
      .setIon(false)
      .setAsmJS(false)
      .setNativeRegExp(false);
}

void MozjsGlobalEnvironment::SetReportEvalCallback(
    const base::Closure& report_eval) {
  DCHECK(thread_checker_.CalledOnValidThread());
  report_eval_ = report_eval;
}

void MozjsGlobalEnvironment::Bind(const std::string& identifier,
                                  const scoped_refptr<Wrappable>& impl) {
  TRACK_MEMORY_SCOPE("Javascript");
  JSAutoRequest auto_request(context_);
  JSAutoCompartment auto_compartment(context_, global_object_proxy_);

  JS::RootedObject wrapper_proxy(context_,
                                 wrapper_factory_->GetWrapperProxy(impl));
  JS::RootedObject global_object(
      context_, js::GetProxyTargetObject(global_object_proxy_));

  JS::RootedValue wrapper_value(context_);
  wrapper_value.setObject(*wrapper_proxy);

  bool success = JS_SetProperty(context_, global_object, identifier.c_str(),
                                wrapper_value);

  DCHECK(success);
}

ScriptValueFactory* MozjsGlobalEnvironment::script_value_factory() {
  DCHECK(script_value_factory_);
  return script_value_factory_.get();
}

void MozjsGlobalEnvironment::EvaluateAutomatics() {
  EvaluateEmbeddedScript(
      MozjsEmbeddedResources::promise_min_js,
      sizeof(MozjsEmbeddedResources::promise_min_js),
      "promise.min.js");
  EvaluateEmbeddedScript(
      MozjsEmbeddedResources::byte_length_queuing_strategy_js,
      sizeof(MozjsEmbeddedResources::byte_length_queuing_strategy_js),
      "byte_length_queuing_strategy.js");
  EvaluateEmbeddedScript(
      MozjsEmbeddedResources::count_queuing_strategy_js,
      sizeof(MozjsEmbeddedResources::count_queuing_strategy_js),
      "count_queuing_strategy.js");
  EvaluateEmbeddedScript(
      MozjsEmbeddedResources::readable_stream_js,
      sizeof(MozjsEmbeddedResources::readable_stream_js),
      "readable_stream.js");
  EvaluateEmbeddedScript(
      MozjsEmbeddedResources::fetch_js,
      sizeof(MozjsEmbeddedResources::fetch_js),
      "fetch.js");
}

InterfaceData* MozjsGlobalEnvironment::GetInterfaceData(intptr_t key) {
  CachedInterfaceData::iterator it = cached_interface_data_.find(key);
  if (it != cached_interface_data_.end()) {
    return it->second;
  }
  return NULL;
}

void MozjsGlobalEnvironment::DoSweep() {
  TRACK_MEMORY_SCOPE("Javascript");
  weak_object_manager_.SweepUnmarkedObjects();
  // Remove NULL references after sweeping weak references.
  referenced_objects_->RemoveNullReferences();
}

void MozjsGlobalEnvironment::BeginGarbageCollection() {
  TRACK_MEMORY_SCOPE("Javascript");
  // It's possible that a GC could be triggered from within the
  // BeginGarbageCollection callback. Only verify that |visisted_wrappables_|
  // is empty the first time we enter.
  garbage_collection_count_++;

  if (garbage_collection_count_ == 1) {
    DCHECK_EQ(visited_wrappables_.size(), 0);
  }
}

void MozjsGlobalEnvironment::EndGarbageCollection() {
  // Reset |visisted_wrappables_|.
  garbage_collection_count_--;
  DCHECK_GE(garbage_collection_count_, 0);
  if (garbage_collection_count_ == 0) {
    visited_wrappables_.clear();
  }
}

MozjsGlobalEnvironment* MozjsGlobalEnvironment::GetFromContext(
    JSContext* context) {
  MozjsGlobalEnvironment* global_proxy =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  DCHECK(global_proxy);
  return global_proxy;
}

void MozjsGlobalEnvironment::SetGlobalObjectProxyAndWrapper(
    JS::HandleObject global_object_proxy,
    const scoped_refptr<Wrappable>& wrappable) {
  DCHECK(!global_object_proxy_);
  DCHECK(global_object_proxy);
  DCHECK(JS_IsGlobalObject(js::GetProxyTargetObject(global_object_proxy)));
  DCHECK(IsProxy(global_object_proxy));

  global_object_proxy_ = global_object_proxy;

  // Global object cached wrapper is not set as usual object.
  // Set the global object cached wrapper, so we can get the object proxy
  // through wrapper handle.
  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromProxyObject(context_, global_object_proxy);

  DCHECK(wrapper_private);

  scoped_ptr<Wrappable::WeakWrapperHandle> object_handle(
      new MozjsWrapperHandle(wrapper_private));
  SetCachedWrapper(wrappable.get(), object_handle.Pass());
}

void MozjsGlobalEnvironment::CacheInterfaceData(intptr_t key,
                                                InterfaceData* interface_data) {
  std::pair<CachedInterfaceData::iterator, bool> pib =
      cached_interface_data_.insert(std::make_pair(key, interface_data));
  DCHECK(pib.second);
}

void MozjsGlobalEnvironment::ReportError(const char* message,
                                         JSErrorReport* report) {
  std::string error_message;
  if (report->errorNumber == JSMSG_CSP_BLOCKED_EVAL) {
    error_message = eval_disabled_message_.value_or(message);
  } else {
    error_message = message;
  }

  if (last_error_message_) {
    *last_error_message_ = error_message;
  } else {
    const char* filename = report->filename ? report->filename : "(none)";
    LOG(ERROR) << "JS Error: " << filename << ":" << report->lineno << ":"
               << report->column << ": " << error_message;
  }
}

void MozjsGlobalEnvironment::TraceFunction(JSTracer* trace, void* data) {
  MozjsGlobalEnvironment* global_object_environment =
      reinterpret_cast<MozjsGlobalEnvironment*>(data);
  if (global_object_environment->global_object_proxy_) {
    JS_CallObjectTracer(trace, &global_object_environment->global_object_proxy_,
                        "MozjsGlobalEnvironment");
  }
  for (CachedInterfaceData::iterator it =
           global_object_environment->cached_interface_data_.begin();
       it != global_object_environment->cached_interface_data_.end(); ++it) {
    InterfaceData* data = it->second;
    // Check whether prototype and interface object for this interface have been
    // created yet or not before attempting to trace them.
    if (data->prototype) {
      JS_CallObjectTracer(trace, &data->prototype, "MozjsGlobalEnvironment");
    }
    if (data->interface_object) {
      JS_CallObjectTracer(trace, &data->interface_object,
                          "MozjsGlobalEnvironment");
    }
  }
  for (CachedWrapperMultiMap::iterator it =
           global_object_environment->kept_alive_objects_.begin();
       it != global_object_environment->kept_alive_objects_.end(); ++it) {
    JS_CallObjectTracer(trace, &it->second, "MozjsGlobalEnvironment");
  }
}

bool MozjsGlobalEnvironment::CheckEval(JSContext* context) {
  TRACK_MEMORY_SCOPE("Javascript");
  MozjsGlobalEnvironment* global_object_proxy = GetFromContext(context);
  DCHECK(global_object_proxy);
  if (!global_object_proxy->report_eval_.is_null()) {
    global_object_proxy->report_eval_.Run();
  }
  return global_object_proxy->eval_enabled_;
}

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