// 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.

#ifndef COBALT_SCRIPT_V8C_V8C_GLOBAL_ENVIRONMENT_H_
#define COBALT_SCRIPT_V8C_V8C_GLOBAL_ENVIRONMENT_H_

#include <string>
#include <unordered_map>
#include <vector>

#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/logging.h"
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/threading/thread_checker.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/v8c/v8c_heap_tracer.h"
#include "cobalt/script/v8c/wrapper_factory.h"
#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

class V8cScriptValueFactory;
class ReferencedObjectMap;
class WeakHandle;

// A wrapper of |v8::Context|, which holds the global object.
class V8cGlobalEnvironment : public GlobalEnvironment,
                             public Wrappable::CachedWrapperAccessor {
 public:
  // Helper function to allow others to retrieve us (a |V8cGlobalEnvironment|)
  // from our |v8::Isolate|.
  static V8cGlobalEnvironment* GetFromIsolate(v8::Isolate* isolate) {
    return static_cast<V8cGlobalEnvironment*>(
        isolate->GetData(kIsolateDataIndex));
  }

  explicit V8cGlobalEnvironment(v8::Isolate* isolate);
  ~V8cGlobalEnvironment() override;

  void CreateGlobalObject() override;
  template <typename GlobalInterface>
  void CreateGlobalObject(
      const scoped_refptr<GlobalInterface>& global_interface,
      EnvironmentSettings* environment_settings);

  bool EvaluateScript(const scoped_refptr<SourceCode>& script,
                      std::string* out_result_utf8) override;

  bool EvaluateScript(
      const scoped_refptr<SourceCode>& script_utf8,
      const scoped_refptr<Wrappable>& owning_object,
      base::optional<ValueHandleHolder::Reference>* out_value_handle) override;

  std::vector<StackFrame> GetStackTrace(int max_frames) override;
  using GlobalEnvironment::GetStackTrace;

  void PreventGarbageCollection(
      const scoped_refptr<Wrappable>& wrappable) override;

  void AllowGarbageCollection(Wrappable* wrappable) override;

  void AddRoot(Traceable* traceable) override;

  void RemoveRoot(Traceable* traceable) override;

  void DisableEval(const std::string& message) override;

  void EnableEval() override;

  void DisableJit() override;

  void SetReportEvalCallback(const base::Closure& report_eval) override;

  void SetReportErrorCallback(
      const ReportErrorCallback& report_error_callback) override;

  void Bind(const std::string& identifier,
            const scoped_refptr<Wrappable>& impl) override;

  ScriptValueFactory* script_value_factory() override;

  v8::Isolate* isolate() const { return isolate_; }
  v8::Local<v8::Context> context() const {
    return v8::Local<v8::Context>::New(isolate_, context_);
  }

  // Check whether we have interface data loaded for interface key |key|.
  bool HasInterfaceData(int key) const;

  // Get interface data for |key|.  Attempting to get interface data for a key
  // that does not have any is a usage error.  Check |HasInterfaceData| first.
  v8::Local<v8::FunctionTemplate> GetInterfaceData(int key) const;

  // Register interface data (which is just |function_template|) for key
  // |key|.  Attempting to add interface data for a key that already has
  // interface data is a usage error.
  void AddInterfaceData(int key,
                        v8::Local<v8::FunctionTemplate> function_template);

  WrapperFactory* wrapper_factory() const { return wrapper_factory_.get(); }

  Wrappable* global_wrappable() const { return global_wrappable_; }

  EnvironmentSettings* GetEnvironmentSettings() const {
    return environment_settings_;
  }

 private:
  // A helper class to trigger a final necessary garbage collection to run
  // finalizer callbacks precisely in between |global_wrappable_| getting
  // propped up and |context_| + |global_object_| getting reset.
  class DestructionHelper {
   public:
    explicit DestructionHelper(v8::Isolate* isolate) : isolate_(isolate) {}
    ~DestructionHelper();

   private:
    v8::Isolate* isolate_;
  };

  static bool AllowCodeGenerationFromStringsCallback(
      v8::Local<v8::Context> context, v8::Local<v8::String> source);

  static void MessageHandler(v8::Local<v8::Message> message,
                             v8::Local<v8::Value> data);

  v8::MaybeLocal<v8::Value> EvaluateScriptInternal(
      const scoped_refptr<SourceCode>& source_code);

  void EvaluateEmbeddedScript(const unsigned char* data, size_t size,
                              const char* filename);

  // Evaluates any automatically included Javascript for the environment.
  void EvaluateAutomatics();

  // Where we store ourselves as embedder private data in our corresponding
  // |v8::Isolate|.
  static const int kIsolateDataIndex = 1;

  base::ThreadChecker thread_checker_;
  // Flag indicating when the destructor is called.
  bool destructing_ = false;
  v8::Isolate* isolate_;

  // Hold an extra reference to the global wrappable in order to properly
  // destruct.  Were we to not do this, finalizers can run in the order (e.g.)
  // document window, which the Cobalt DOM does not support.
  scoped_refptr<Wrappable> global_wrappable_;
  DestructionHelper destruction_helper_;
  v8::Global<v8::Context> context_;
  v8::Global<v8::Object> global_object_;

  scoped_ptr<WrapperFactory> wrapper_factory_;
  scoped_ptr<V8cScriptValueFactory> script_value_factory_;

  // Data that is cached on a per-interface basis. Note that we can get to
  // everything (the function instance, the prototype template, and the
  // instance template) from just the function template.
  std::vector<v8::Eternal<v8::FunctionTemplate>> cached_interface_data_;

  EnvironmentSettings* environment_settings_ = nullptr;

  // If non-NULL, the error message from the ReportErrorHandler will get
  // assigned to this instead of being printed.
  std::string* last_error_message_ = nullptr;

  base::Closure report_eval_;

  ReportErrorCallback report_error_callback_;
};

}  // namespace v8c
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_V8C_V8C_GLOBAL_ENVIRONMENT_H_
