// Copyright 2017 The Cobalt Authors. 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.

#if defined(STARBOARD)
#include "starboard/client_porting/poem/string_leaks_poem.h"
#endif  // defined(STARBOARD)

#include "cobalt/script/v8c/v8c_engine.h"

#include <algorithm>
#include <memory>
#include <string>

#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/c_val.h"
#include "cobalt/browser/stack_size_constants.h"
#include "cobalt/script/v8c/isolate_fellowship.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "starboard/once.h"

namespace cobalt {
namespace script {
namespace v8c {

namespace {

size_t UsedHeapSize(v8::Isolate* isolate) {
  v8::HeapStatistics heap_statistics;
  isolate->GetHeapStatistics(&heap_statistics);
  return heap_statistics.used_heap_size();
}

void GCPrologueCallback(v8::Isolate* isolate, v8::GCType type,
                        v8::GCCallbackFlags) {
  switch (type) {
    case v8::kGCTypeScavenge:
      TRACE_EVENT_BEGIN1("cobalt::script", "MinorGC", "usedHeapSizeBefore",
                         UsedHeapSize(isolate));
      break;
    case v8::kGCTypeMarkSweepCompact:
      TRACE_EVENT_BEGIN2("cobalt::script", "MajorGC", "usedHeapSizeBefore",
                         UsedHeapSize(isolate), "type", "atomic pause");
      break;
    case v8::kGCTypeIncrementalMarking:
      TRACE_EVENT_BEGIN2("cobalt::script", "MajorGC", "usedHeapSizeBefore",
                         UsedHeapSize(isolate), "type", "incremental marking");
      break;
    case v8::kGCTypeProcessWeakCallbacks:
      TRACE_EVENT_BEGIN2("cobalt::script", "MajorGC", "usedHeapSizeBefore",
                         UsedHeapSize(isolate), "type", "weak processing");
      break;
    default:
      NOTREACHED();
  }
}

void GCEpilogueCallback(v8::Isolate* isolate, v8::GCType type,
                        v8::GCCallbackFlags) {
  switch (type) {
    case v8::kGCTypeScavenge:
      TRACE_EVENT_END1("cobalt::script", "MinorGC", "usedHeapSizeAfter",
                       UsedHeapSize(isolate));
      break;
    case v8::kGCTypeMarkSweepCompact:
      TRACE_EVENT_END1("cobalt::script", "MajorGC", "usedHeapSizeAfter",
                       UsedHeapSize(isolate));
      break;
    case v8::kGCTypeIncrementalMarking:
      TRACE_EVENT_END1("cobalt::script", "MajorGC", "usedHeapSizeAfter",
                       UsedHeapSize(isolate));
      break;
    case v8::kGCTypeProcessWeakCallbacks:
      TRACE_EVENT_END1("cobalt::script", "MajorGC", "usedHeapSizeAfter",
                       UsedHeapSize(isolate));
      break;
    default:
      NOTREACHED();
  }
}

}  // namespace

V8cEngine::V8cEngine(const Options& options) : options_(options) {
  TRACE_EVENT0("cobalt::script", "V8cEngine::V8cEngine()");

  auto* isolate_fellowship = IsolateFellowship::GetInstance();

  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator =
      isolate_fellowship->array_buffer_allocator;
#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
  auto* startup_data = &isolate_fellowship->startup_data;
  if (startup_data->data != nullptr) {
    create_params.snapshot_blob = startup_data;
  } else {
    // Technically possible to attempt to recover here, but hitting this
    // indicates that something is probably seriously wrong.
    LOG(WARNING) << "Isolate fellowship startup data was null, this will "
                    "significantly slow down startup time.";
  }
#endif  // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)

  isolate_ = v8::Isolate::New(create_params);
  CHECK(isolate_);
  isolate_fellowship->platform->RegisterIsolateOnThread(
      isolate_, base::MessageLoop::current());

  // There are 2 total isolate data slots, one for the sole |V8cEngine| (us),
  // and one for the |V8cGlobalEnvironment|.
  const int kTotalIsolateDataSlots = 2;
  DCHECK_GE(v8::Isolate::GetNumberOfDataSlots(), kTotalIsolateDataSlots);
  isolate_->SetData(kIsolateDataIndex, this);

  v8c_heap_tracer_.reset(new V8cHeapTracer(isolate_));
  isolate_->SetEmbedderHeapTracer(v8c_heap_tracer_.get());

  isolate_->AddGCPrologueCallback(GCPrologueCallback);
  isolate_->AddGCEpilogueCallback(GCEpilogueCallback);

  // The V8 |SetStackLimit|'s parameter is the memory address that it should not
  // pass, as opposed to the size of the stack that it should use.  We set it
  // to 3/4 of the main thread's stack size to cover for the space underneath
  // the stack currently, and the space we want to reserve on top of the stack
  // for when JavaScript calls back into C++ bindings.
  uintptr_t here = reinterpret_cast<uintptr_t>(&here);
  isolate_->SetStackLimit(here -
                          (3 * cobalt::browser::kWebModuleStackSize) / 4);
}

V8cEngine::~V8cEngine() {
  TRACE_EVENT0("cobalt::script", "V8cEngine::~V8cEngine");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  IsolateFellowship::GetInstance()->platform->UnregisterIsolateOnThread(
      isolate_);
  // Send a low memory notification to V8 in order to force a garbage
  // collection before shut down.  This is required to run weak callbacks that
  // are responsible for freeing native objects that live in the internal
  // fields of V8 objects.  In the future, we should consider investigating if
  // there are startup performance wins to be made by delaying this work until
  // later (e.g., does the GC of the splash screen web module dying hurt us?).
  isolate_->LowMemoryNotification();
  isolate_->Dispose();
  isolate_ = nullptr;
}

scoped_refptr<GlobalEnvironment> V8cEngine::CreateGlobalEnvironment() {
  TRACE_EVENT0("cobalt::script", "V8cEngine::CreateGlobalEnvironment()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  return new V8cGlobalEnvironment(isolate_);
}

void V8cEngine::CollectGarbage() {
  TRACE_EVENT0("cobalt::script", "V8cEngine::CollectGarbage()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  isolate_->LowMemoryNotification();
}

void V8cEngine::AdjustAmountOfExternalAllocatedMemory(int64_t bytes) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  isolate_->AdjustAmountOfExternalAllocatedMemory(bytes);
}

bool V8cEngine::RegisterErrorHandler(JavaScriptEngine::ErrorHandler handler) {
  error_handler_ = handler;
  return true;
}

HeapStatistics V8cEngine::GetHeapStatistics() {
  v8::HeapStatistics v8_heap_statistics;
  isolate_->GetHeapStatistics(&v8_heap_statistics);
  return {v8_heap_statistics.total_heap_size(),
          v8_heap_statistics.used_heap_size()};
}

}  // namespace v8c

// static
std::unique_ptr<JavaScriptEngine> JavaScriptEngine::CreateEngine(
    const JavaScriptEngine::Options& options) {
  TRACE_EVENT0("cobalt::script", "JavaScriptEngine::CreateEngine()");
  return std::unique_ptr<JavaScriptEngine>(new v8c::V8cEngine(options));
}

std::string GetJavaScriptEngineNameAndVersion() {
  return std::string("v8/") + v8::V8::GetVersion();
}

}  // namespace script
}  // namespace cobalt
