// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_ASYNC_HOOKS_WRAPPER_H_
#define V8_ASYNC_HOOKS_WRAPPER_H_

#include <stack>

#include "include/v8.h"
#include "src/objects.h"

namespace v8 {

typedef double async_id_t;

struct AsyncContext {
  async_id_t execution_async_id;
  async_id_t trigger_async_id;
};

class AsyncHooksWrap {
 public:
  explicit AsyncHooksWrap(Isolate* isolate) {
    enabled_ = false;
    isolate_ = isolate;
  }
  void Enable();
  void Disable();
  bool IsEnabled() const { return enabled_; }

  inline v8::Local<v8::Function> init_function() const;
  inline void set_init_function(v8::Local<v8::Function> value);
  inline v8::Local<v8::Function> before_function() const;
  inline void set_before_function(v8::Local<v8::Function> value);
  inline v8::Local<v8::Function> after_function() const;
  inline void set_after_function(v8::Local<v8::Function> value);
  inline v8::Local<v8::Function> promiseResolve_function() const;
  inline void set_promiseResolve_function(v8::Local<v8::Function> value);

 private:
  Isolate* isolate_;

  Persistent<v8::Function> init_function_;
  Persistent<v8::Function> before_function_;
  Persistent<v8::Function> after_function_;
  Persistent<v8::Function> promiseResolve_function_;

  bool enabled_;
};

class AsyncHooks {
 public:
  explicit AsyncHooks(Isolate* isolate) {
    isolate_ = isolate;

    AsyncContext ctx;
    ctx.execution_async_id = 1;
    ctx.trigger_async_id = 0;
    asyncContexts.push(ctx);
    current_async_id = 1;

    Initialize();
  }
  ~AsyncHooks() { Deinitialize(); }

  async_id_t GetExecutionAsyncId() const;
  async_id_t GetTriggerAsyncId() const;

  Local<Object> CreateHook(const v8::FunctionCallbackInfo<v8::Value>& args);

  Persistent<FunctionTemplate> async_hook_ctor;

 private:
  std::vector<AsyncHooksWrap*> async_wraps_;
  Isolate* isolate_;
  Persistent<ObjectTemplate> async_hooks_templ;
  Persistent<Private> async_id_smb;
  Persistent<Private> trigger_id_smb;

  void Initialize();
  void Deinitialize();

  static void ShellPromiseHook(PromiseHookType type, Local<Promise> promise,
                               Local<Value> parent);
  static void PromiseHookDispatch(PromiseHookType type, Local<Promise> promise,
                                  Local<Value> parent, AsyncHooksWrap* wrap,
                                  AsyncHooks* hooks);

  std::stack<AsyncContext> asyncContexts;
  async_id_t current_async_id;
};

}  // namespace v8

#endif  // V8_ASYNC_HOOKS_WRAPPER_H_
