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

#include <algorithm>
#include <string>

#include "base/debug/trace_event.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "cobalt/base/c_val.h"
#include "cobalt/browser/stack_size_constants.h"
#include "cobalt/script/mozjs/mozjs_global_environment.h"
#include "cobalt/script/mozjs/util/stack_trace_helpers.h"
#include "third_party/mozjs/cobalt_config/include/jscustomallocator.h"
#include "third_party/mozjs/js/src/jsapi.h"
#include "third_party/mozjs/js/src/jsdbgapi.h"

namespace cobalt {
namespace script {
namespace mozjs {
namespace {
// Trigger garbage collection this many seconds after the last one.
const int kGarbageCollectionIntervalSeconds = 60;

JSBool CheckAccessStub(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>,
                       JSAccessMode, JS::MutableHandle<JS::Value>) {
  return true;
}

JSSecurityCallbacks security_callbacks = {
  CheckAccessStub,
  MozjsGlobalEnvironment::CheckEval
};

class EngineStats {
 public:
  EngineStats();

  static EngineStats* GetInstance() {
    return Singleton<EngineStats,
                     StaticMemorySingletonTraits<EngineStats> >::get();
  }

  void EngineCreated() { ++engine_count_; }
  void EngineDestroyed() { --engine_count_; }

  size_t UpdateMemoryStatsAndReturnReserved() {
    // Accessing CVals triggers a lock, so rely on local variables when
    // possible to avoid unecessary locking.
    size_t allocated_memory =
        MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
    size_t mapped_memory =
        MemoryAllocatorReporter::Get()->GetCurrentBytesMapped();

    allocated_memory_ = allocated_memory;
    mapped_memory_ = mapped_memory;

    return allocated_memory + mapped_memory;
  }

 private:
  base::CVal<int> engine_count_;
  base::CVal<base::cval::SizeInBytes, base::CValPublic> allocated_memory_;
  base::CVal<base::cval::SizeInBytes, base::CValPublic> mapped_memory_;
};

EngineStats::EngineStats()
    : engine_count_("Count.JS.Engine", 0,
                    "Total JavaScript engine registered."),
      allocated_memory_("Memory.JS.AllocatedMemory", 0,
                        "JS memory occupied by the Mozjs allocator."),
      mapped_memory_("Memory.JS.MappedMemory", 0, "JS mapped memory.") {}

// Pretend we always preserve wrappers since we never call
// SetPreserveWrapperCallback anywhere else. This is necessary for
// TryPreserveReflector called by WeakMap to not crash. Disabling
// bindings to WeakMap does not appear to be an easy option because
// of its use in selfhosted.js. See bugzilla discussion linked where
// they decided to include a similar dummy in the mozjs shell.
// https://bugzilla.mozilla.org/show_bug.cgi?id=829798
bool DummyPreserveWrapperCallback(JSContext *cx, JSObject *obj) {
  return true;
}
}  // namespace

MozjsEngine::MozjsEngine(const Options& options)
    : accumulated_extra_memory_cost_(0),
      moz_options_(options) {
  TRACE_EVENT0("cobalt::script", "MozjsEngine::MozjsEngine()");
  // TODO: Investigate the benefit of helper threads and things like
  // parallel compilation.
  runtime_ = JS_NewRuntime(moz_options_.js_options.gc_threshold_bytes,
                           JS_NO_HELPER_THREADS);
  CHECK(runtime_);

  // Sets the size of the native stack that should not be exceeded.
  // Setting three quarters of the web module stack size to ensure that native
  // stack won't exceed the stack size.
  JS_SetNativeStackQuota(runtime_,
                         cobalt::browser::kWebModuleStackSize / 4 * 3);

  JS_SetRuntimePrivate(runtime_, this);

  JS_SetSecurityCallbacks(runtime_, &security_callbacks);

  // Use incremental garbage collection.
  JS_SetGCParameter(runtime_, JSGC_MODE, JSGC_MODE_INCREMENTAL);

  // Allow Spidermonkey to allocate as much memory as it needs. If this limit
  // is set we could limit the memory used by JS and "gracefully" restart,
  // for example.
  JS_SetGCParameter(runtime_, JSGC_MAX_BYTES, 0xffffffff);

  // Callback to be called whenever a JSContext is created or destroyed for this
  // JSRuntime.
  JS_SetContextCallback(runtime_, &MozjsEngine::ContextCallback);

  // Callback to be called at different points during garbage collection.
  JS_SetGCCallback(runtime_, &MozjsEngine::GCCallback);

  // Callback to be called during garbage collection during the sweep phase.
  JS_SetFinalizeCallback(runtime_, &MozjsEngine::FinalizeCallback);

  js::SetPreserveWrapperCallback(runtime_, DummyPreserveWrapperCallback);

  EngineStats::GetInstance()->EngineCreated();

  if (MessageLoop::current()) {
    gc_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(
                                   kGarbageCollectionIntervalSeconds),
                    this, &MozjsEngine::TimerGarbageCollect);
  }
}

MozjsEngine::~MozjsEngine() {
  DCHECK(thread_checker_.CalledOnValidThread());
  EngineStats::GetInstance()->EngineDestroyed();
  JS_DestroyRuntime(runtime_);
}

scoped_refptr<GlobalEnvironment> MozjsEngine::CreateGlobalEnvironment() {
  TRACE_EVENT0("cobalt::script", "MozjsEngine::CreateGlobalEnvironment()");
  DCHECK(thread_checker_.CalledOnValidThread());
  return new MozjsGlobalEnvironment(runtime_, moz_options_.js_options);
}

void MozjsEngine::CollectGarbage() {
  TRACE_EVENT0("cobalt::script", "MozjsEngine::CollectGarbage()");
  DCHECK(thread_checker_.CalledOnValidThread());
  JS_GC(runtime_);
}

void MozjsEngine::ReportExtraMemoryCost(size_t bytes) {
  DCHECK(thread_checker_.CalledOnValidThread());
  accumulated_extra_memory_cost_ += bytes;

  const bool do_collect_garbage = accumulated_extra_memory_cost_ >
                                  moz_options_.js_options.gc_threshold_bytes;
  if (do_collect_garbage) {
    accumulated_extra_memory_cost_ = 0;
    CollectGarbage();
  }
}

bool MozjsEngine::RegisterErrorHandler(JavaScriptEngine::ErrorHandler handler) {
  error_handler_ = handler;
  JSDebugErrorHook hook = ErrorHookCallback;
  void* closure = this;
  JS_SetDebugErrorHook(runtime_, hook, closure);
  return true;
}

void MozjsEngine::TimerGarbageCollect() {
  TRACE_EVENT0("cobalt::script", "MozjsEngine::TimerGarbageCollect()");
  CollectGarbage();
}

JSBool MozjsEngine::ContextCallback(JSContext* context, unsigned context_op) {
  JSRuntime* runtime = JS_GetRuntime(context);
  MozjsEngine* engine =
      static_cast<MozjsEngine*>(JS_GetRuntimePrivate(runtime));
  DCHECK(engine->thread_checker_.CalledOnValidThread());
  if (context_op == JSCONTEXT_NEW) {
    engine->contexts_.push_back(context);
  } else if (context_op == JSCONTEXT_DESTROY) {
    ContextVector::iterator it =
        std::find(engine->contexts_.begin(), engine->contexts_.end(), context);
    if (it != engine->contexts_.end()) {
      engine->contexts_.erase(it);
    }
  }
  return true;
}

void MozjsEngine::GCCallback(JSRuntime* runtime, JSGCStatus status) {
  MozjsEngine* engine =
      static_cast<MozjsEngine*>(JS_GetRuntimePrivate(runtime));
  if (status == JSGC_END) {
    engine->accumulated_extra_memory_cost_ = 0;
    // Reset the GC timer to avoid having the timed GC come soon after this one.
    if (engine->gc_timer_.IsRunning()) {
      engine->gc_timer_.Reset();
    }
  }
  for (int i = 0; i < engine->contexts_.size(); ++i) {
    MozjsGlobalEnvironment* global_environment =
        MozjsGlobalEnvironment::GetFromContext(engine->contexts_[i]);
    if (status == JSGC_BEGIN) {
      TRACE_EVENT_BEGIN0("cobalt::script", "SpiderMonkey Garbage Collection");
      global_environment->BeginGarbageCollection();
    } else if (status == JSGC_END) {
      global_environment->EndGarbageCollection();
      TRACE_EVENT_END0("cobalt::script", "SpiderMonkey Garbage Collection");
    }
  }
}

void MozjsEngine::FinalizeCallback(JSFreeOp* free_op, JSFinalizeStatus status,
                                   JSBool is_compartment) {
  TRACE_EVENT0("cobalt::script", "MozjsEngine::FinalizeCallback()");
  MozjsEngine* engine =
      static_cast<MozjsEngine*>(JS_GetRuntimePrivate(free_op->runtime()));
  DCHECK(engine->thread_checker_.CalledOnValidThread());
  if (status == JSFINALIZE_GROUP_START) {
    for (int i = 0; i < engine->contexts_.size(); ++i) {
      MozjsGlobalEnvironment* global_environment =
          MozjsGlobalEnvironment::GetFromContext(engine->contexts_[i]);
      global_environment->DoSweep();
    }
  }
}

JSBool MozjsEngine::ErrorHookCallback(JSContext* context, const char* message,
                                      JSErrorReport* report, void* closure) {
  MozjsEngine* this_ptr = static_cast<MozjsEngine*>(closure);
  return this_ptr->ReportJSError(context, message, report);
}

JSBool MozjsEngine::ReportJSError(JSContext* context, const char* message,
                                  JSErrorReport* report) {
  const bool is_invalid =
      error_handler_.is_null() || !report || !report->filename;

  if (is_invalid) {
    return true;  // Allow error to propagate in the mozilla engine.
  }

  // Report errors, warnings and uncaught exceptions. All other errors
  // (like strict warnings) are ignored.
  const bool do_report_error =
      (report->flags == JSREPORT_ERROR) ||
      (report->flags & JSREPORT_WARNING) ||
      (report->errorNumber == JSMSG_UNCAUGHT_EXCEPTION);

  if (do_report_error) {
    std::string file_name = report->filename;
    // Line/column can be zero for internal javascript exceptions. In this
    // case set the values to 1, otherwise the base::SourceLocation object
    // below will dcheck.
    int line = std::max<int>(1, report->lineno);
    int column = std::max<int>(1, report->column);
    if (file_name.empty()) {
      file_name = "<internal exception>";
    }
    base::SourceLocation source_location(file_name, line, column);
    error_handler_.Run(source_location, message);
  }

  return true;  // Allow error to propagate in the mozilla engine.
}

}  // namespace mozjs

scoped_ptr<JavaScriptEngine> JavaScriptEngine::CreateEngine(
    const JavaScriptEngine::Options& options) {
  TRACE_EVENT0("cobalt::script", "JavaScriptEngine::CreateEngine()");
  mozjs::MozjsEngine::Options moz_options(options);
  return make_scoped_ptr<JavaScriptEngine>(
      new mozjs::MozjsEngine(moz_options));
}

size_t JavaScriptEngine::UpdateMemoryStatsAndReturnReserved() {
  return mozjs::EngineStats::GetInstance()
      ->UpdateMemoryStatsAndReturnReserved();
}

}  // namespace script
}  // namespace cobalt
