// 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.
#ifndef COBALT_SCRIPT_MOZJS_MOZJS_GLOBAL_ENVIRONMENT_H_
#define COBALT_SCRIPT_MOZJS_MOZJS_GLOBAL_ENVIRONMENT_H_

#include <string>
#include <vector>

#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/mozjs/interface_data.h"
#include "cobalt/script/mozjs/util/exception_helpers.h"
#include "cobalt/script/mozjs/weak_heap_object_manager.h"
#include "cobalt/script/mozjs/wrapper_factory.h"
#include "third_party/mozjs/js/src/jsapi.h"
#include "third_party/mozjs/js/src/jsproxy.h"

namespace cobalt {
namespace script {
namespace mozjs {

class MozjsScriptValueFactory;
class ReferencedObjectMap;
class WeakHandle;

// Manages a handle to a JavaScript engine's global object. The lifetime of
// the global object is not necessarily tied to the lifetime of the proxy.
class MozjsGlobalEnvironment : public GlobalEnvironment,
                               public Wrappable::CachedWrapperAccessor {
 public:
  MozjsGlobalEnvironment(JSRuntime* runtime,
                         const JavaScriptEngine::Options& options);
  ~MozjsGlobalEnvironment() OVERRIDE;

  void CreateGlobalObject() OVERRIDE;

  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<OpaqueHandleHolder::Reference>*
                          out_opaque_handle) OVERRIDE;

  std::vector<StackFrame> GetStackTrace(int max_frames = 0) OVERRIDE;

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

  void AllowGarbageCollection(
      const scoped_refptr<Wrappable>& wrappable) OVERRIDE;

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

  void EnableEval() OVERRIDE;

  void DisableJit() OVERRIDE;

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

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

  ScriptValueFactory* script_value_factory() OVERRIDE;

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

  JSContext* context() const { return context_; }

  JSObject* global_object_proxy() const { return global_object_proxy_; }
  JSObject* global_object() const {
    return js::GetProxyTargetObject(global_object_proxy_);
  }

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

  ReferencedObjectMap* referenced_objects() {
    return referenced_objects_.get();
  }

  WeakHeapObjectManager* weak_object_manager() { return &weak_object_manager_; }

  base::hash_set<Wrappable*>* visited_wrappables() {
    return &visited_wrappables_;
  }

  // Used for CallWith=EnvironmentSettings
  void SetEnvironmentSettings(EnvironmentSettings* environment_settings) {
    DCHECK(!environment_settings_);
    DCHECK(environment_settings);
    environment_settings_ = environment_settings;
  }

  EnvironmentSettings* GetEnvironmentSettings() const {
    return environment_settings_;
  }

  void SetGlobalObjectProxyAndWrapper(
      JS::HandleObject global_object_proxy,
      const scoped_refptr<Wrappable>& wrappable);

  // Any tracked InterfaceData will have it's GC handles visited and marked as
  // roots. The MozjsGlobalEnvironment takes ownership of the InterfaceData
  // instances and will destroy them.
  void CacheInterfaceData(intptr_t key, InterfaceData* interface_data);
  InterfaceData* GetInterfaceData(intptr_t key);

  // This will be called during garbage collection after GC objects have been
  // marked, but before they have been finalized. This allows an opportunity to
  // sweep away references to GC objects that will be deleted.
  void DoSweep();

  void BeginGarbageCollection();
  void EndGarbageCollection();

  static MozjsGlobalEnvironment* GetFromContext(JSContext* context);

  // This will be called every time an attempt is made to use eval() and
  // friends. If it returns false, then the ReportErrorHandler will be fired
  // with an error that eval() is disabled.
  static JSBool CheckEval(JSContext* context);

 private:
  bool EvaluateScriptInternal(const scoped_refptr<SourceCode>& source_code,
                              JS::MutableHandleValue out_result);

  static void ReportErrorHandler(JSContext* context, const char* message,
                                 JSErrorReport* report);

  static void TraceFunction(JSTracer* trace, void* data);

  // Helper struct to ensure the context is destroyed in the correct order
  // relative to the MozjsGlobalEnvironment's other members.
  struct ContextDestructor {
    explicit ContextDestructor(JSContext** context) : context(context) {}
    ~ContextDestructor() { JS_DestroyContext(*context); }
    JSContext** context;
  };

  typedef base::hash_map<intptr_t, InterfaceData*> CachedInterfaceData;
  typedef base::hash_multimap<Wrappable*, JS::Heap<JSObject*> >
      CachedWrapperMultiMap;

  base::ThreadChecker thread_checker_;
  JSContext* context_;
  int garbage_collection_count_;
  WeakHeapObjectManager weak_object_manager_;
  CachedWrapperMultiMap kept_alive_objects_;
  scoped_ptr<ReferencedObjectMap> referenced_objects_;
  CachedInterfaceData cached_interface_data_;
  STLValueDeleter<CachedInterfaceData> cached_interface_data_deleter_;
  ContextDestructor context_destructor_;
  scoped_ptr<WrapperFactory> wrapper_factory_;
  scoped_ptr<MozjsScriptValueFactory> script_value_factory_;
  JS::Heap<JSObject*> global_object_proxy_;
  EnvironmentSettings* environment_settings_;
  // TODO: Should be |std::unordered_set| once C++11 is enabled.
  base::hash_set<Wrappable*> visited_wrappables_;

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

  bool eval_enabled_;
  base::optional<std::string> eval_disabled_message_;
  base::Closure report_eval_;

  friend class GlobalObjectProxy;
};

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

#endif  // COBALT_SCRIPT_MOZJS_MOZJS_GLOBAL_ENVIRONMENT_H_
