#ifndef SRC_NODE_CONTEXTIFY_H_
#define SRC_NODE_CONTEXTIFY_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "base_object-inl.h"
#include "cppgc_helpers-inl.h"
#include "node_context_data.h"
#include "node_errors.h"

namespace node {
class ExternalReferenceRegistry;

namespace contextify {

struct ContextOptions {
  v8::Local<v8::String> name;
  v8::Local<v8::String> origin;
  v8::Local<v8::Boolean> allow_code_gen_strings;
  v8::Local<v8::Boolean> allow_code_gen_wasm;
  std::unique_ptr<v8::MicrotaskQueue> own_microtask_queue;
  v8::Local<v8::Symbol> host_defined_options_id;
  bool vanilla = false;
};

/**
 * The memory management of a vm context is as follows:
 *
 *                                                          user code
 *                                                              │
 *                          As global proxy or                  ▼
 *     ┌──────────────┐  kSandboxObject embedder data   ┌────────────────┐
 * ┌─► │  V8 Context  │────────────────────────────────►│ Wrapper holder │
 * │   └──────────────┘                                 └───────┬────────┘
 * │         ▲  Object constructor/creation context             │
 * │         │                                                  │
 * │  ┌──────┴────────────┐  contextify_context_private_symbol  │
 * │  │ ContextifyContext │◄────────────────────────────────────┘
 * │  │   JS Wrapper      │◄──────────► ┌─────────────────────────┐
 * │  └───────────────────┘  cppgc      │ node::ContextifyContext │
 * │                                    │       C++ Object        │
 * └──────────────────────────────────► └─────────────────────────┘
 *     v8::TracedReference / ContextEmbedderIndex::kContextifyContext
 *
 * There are two possibilities for the "wrapper holder":
 *
 * 1. When vm.constants.DONT_CONTEXTIFY is used, the wrapper holder is the V8
 *    context's global proxy object
 * 2. Otherwise it's the arbitrary "sandbox object" that users pass into
 *    vm.createContext() or a new empty object created internally if they pass
 *    undefined.
 *
 * In 2, the global object of the new V8 context is created using
 * global_object_template with interceptors that perform any requested
 * operations on the global object in the context first on the sandbox object
 * living outside of the new context, then fall back to the global proxy of the
 * new context.
 *
 * It's critical for the user-accessible wrapper holder to keep the
 * ContextifyContext wrapper alive via contextify_context_private_symbol
 * so that the V8 context is always available to the user while they still
 * hold the vm "context" object alive.
 *
 * It's also critical for the V8 context to keep the wrapper holder
 * (specifically, the "sandbox object" if users pass one) as well as the
 * node::ContextifyContext C++ object alive, so that when the code
 * runs inside the object and accesses the global object, the interceptors
 * can still access the "sandbox object" and perform operations
 * on them, even if users already relinquish access to the outer
 * "sandbox object".
 *
 * The v8::TracedReference and the ContextEmbedderIndex::kContextifyContext
 * slot in the context only act as shortcuts between
 * the node::ContextifyContext C++ object and the V8 context.
 */
class ContextifyContext final : CPPGC_MIXIN(ContextifyContext) {
 public:
  SET_CPPGC_NAME(ContextifyContext)
  void Trace(cppgc::Visitor* visitor) const final;
  SET_NO_MEMORY_INFO()

  ContextifyContext(Environment* env,
                    v8::Local<v8::Object> wrapper,
                    v8::Local<v8::Context> v8_context,
                    ContextOptions* options);

  // The destructors don't need to do anything because when the wrapper is
  // going away, the context is already going away or otherwise it would've
  // been holding the wrapper alive, so there's no need to reset the pointers
  // in the context. Also, any global handles to the context would've been
  // empty at this point, and the per-Environment context tracking code is
  // capable of dealing with empty handles from contexts purged elsewhere.
  ~ContextifyContext() = default;

  static v8::MaybeLocal<v8::Context> CreateV8Context(
      v8::Isolate* isolate,
      v8::Local<v8::ObjectTemplate> object_template,
      const SnapshotData* snapshot_data,
      v8::MicrotaskQueue* queue);
  static void CreatePerIsolateProperties(IsolateData* isolate_data,
                                         v8::Local<v8::ObjectTemplate> target);
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);

  static ContextifyContext* ContextFromContextifiedSandbox(
      Environment* env, const v8::Local<v8::Object>& wrapper_holder);

  inline v8::Local<v8::Context> context() const {
    return context_.Get(env()->isolate());
  }

  inline v8::Local<v8::Object> global_proxy() const {
    return context()->Global();
  }

  inline v8::Local<v8::Object> sandbox() const {
    // Only vanilla contexts have undefined sandboxes. sandbox() is only used by
    // interceptors who are not supposed to be called on vanilla contexts.
    v8::Local<v8::Value> result =
        context()->GetEmbedderData(ContextEmbedderIndex::kSandboxObject);
    CHECK(!result->IsUndefined());
    return result.As<v8::Object>();
  }

  inline v8::MicrotaskQueue* microtask_queue() const {
    return microtask_queue_.get();
  }

  template <typename T>
  static ContextifyContext* Get(const v8::PropertyCallbackInfo<T>& args);
  static ContextifyContext* Get(v8::Local<v8::Object> object);

  static void InitializeGlobalTemplates(IsolateData* isolate_data);

 private:
  static ContextifyContext* New(Environment* env,
                                v8::Local<v8::Object> sandbox_obj,
                                ContextOptions* options);
  // Initialize a context created from CreateV8Context()
  static ContextifyContext* New(v8::Local<v8::Context> ctx,
                                Environment* env,
                                v8::Local<v8::Object> sandbox_obj,
                                ContextOptions* options);

  static bool IsStillInitializing(const ContextifyContext* ctx);
  static void MakeContext(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void IsContext(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Intercepted PropertyQueryCallback(
      v8::Local<v8::Name> property,
      const v8::PropertyCallbackInfo<v8::Integer>& args);
  static v8::Intercepted PropertyGetterCallback(
      v8::Local<v8::Name> property,
      const v8::PropertyCallbackInfo<v8::Value>& args);
  static v8::Intercepted PropertySetterCallback(
      v8::Local<v8::Name> property,
      v8::Local<v8::Value> value,
      const v8::PropertyCallbackInfo<void>& args);
  static v8::Intercepted PropertyDescriptorCallback(
      v8::Local<v8::Name> property,
      const v8::PropertyCallbackInfo<v8::Value>& args);
  static v8::Intercepted PropertyDefinerCallback(
      v8::Local<v8::Name> property,
      const v8::PropertyDescriptor& desc,
      const v8::PropertyCallbackInfo<void>& args);
  static v8::Intercepted PropertyDeleterCallback(
      v8::Local<v8::Name> property,
      const v8::PropertyCallbackInfo<v8::Boolean>& args);
  static void PropertyEnumeratorCallback(
      const v8::PropertyCallbackInfo<v8::Array>& args);
  static v8::Intercepted IndexedPropertyQueryCallback(
      uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& args);
  static v8::Intercepted IndexedPropertyGetterCallback(
      uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& args);
  static v8::Intercepted IndexedPropertySetterCallback(
      uint32_t index,
      v8::Local<v8::Value> value,
      const v8::PropertyCallbackInfo<void>& args);
  static v8::Intercepted IndexedPropertyDescriptorCallback(
      uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& args);
  static v8::Intercepted IndexedPropertyDefinerCallback(
      uint32_t index,
      const v8::PropertyDescriptor& desc,
      const v8::PropertyCallbackInfo<void>& args);
  static v8::Intercepted IndexedPropertyDeleterCallback(
      uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& args);
  static void IndexedPropertyEnumeratorCallback(
      const v8::PropertyCallbackInfo<v8::Array>& args);

  v8::TracedReference<v8::Context> context_;
  std::unique_ptr<v8::MicrotaskQueue> microtask_queue_;
};

class ContextifyScript final : CPPGC_MIXIN(ContextifyScript) {
 public:
  SET_CPPGC_NAME(ContextifyScript)
  void Trace(cppgc::Visitor* visitor) const final;
  SET_NO_MEMORY_INFO()

  ContextifyScript(Environment* env, v8::Local<v8::Object> object);
  ~ContextifyScript() override;

  v8::Local<v8::UnboundScript> unbound_script() const;
  void set_unbound_script(v8::Local<v8::UnboundScript>);

  static void CreatePerIsolateProperties(IsolateData* isolate_data,
                                         v8::Local<v8::ObjectTemplate> target);
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
  static ContextifyScript* New(Environment* env, v8::Local<v8::Object> object);
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static bool InstanceOf(Environment* env, const v8::Local<v8::Value>& args);
  static void CreateCachedData(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void RunInContext(const v8::FunctionCallbackInfo<v8::Value>& args);
  static bool EvalMachine(v8::Local<v8::Context> context,
                          Environment* env,
                          const int64_t timeout,
                          const bool display_errors,
                          const bool break_on_sigint,
                          const bool break_on_first_line,
                          v8::MicrotaskQueue* microtask_queue,
                          const v8::FunctionCallbackInfo<v8::Value>& args);

 private:
  v8::TracedReference<v8::UnboundScript> script_;
};

class ContextifyFunction final {
 public:
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
  static void CreatePerIsolateProperties(IsolateData* isolate_data,
                                         v8::Local<v8::ObjectTemplate> target);

  static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::MaybeLocal<v8::Object> CompileFunctionAndCacheResult(
      Environment* env,
      v8::Local<v8::Context> parsing_context,
      v8::ScriptCompiler::Source* source,
      v8::LocalVector<v8::String> params,
      v8::LocalVector<v8::Object> context_extensions,
      v8::ScriptCompiler::CompileOptions options,
      bool produce_cached_data,
      v8::Local<v8::Symbol> id_symbol,
      const errors::TryCatchScope& try_catch);

 private:
  ContextifyFunction() = delete;
  ~ContextifyFunction() = delete;
};

v8::Maybe<void> StoreCodeCacheResult(
    Environment* env,
    v8::Local<v8::Object> target,
    v8::ScriptCompiler::CompileOptions compile_options,
    const v8::ScriptCompiler::Source& source,
    bool produce_cached_data,
    std::unique_ptr<v8::ScriptCompiler::CachedData> new_cached_data);

}  // namespace contextify
}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#endif  // SRC_NODE_CONTEXTIFY_H_
