// Copyright (c) 2013 The Chromium Embedded Framework 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 CEF_LIBCEF_RENDERER_V8_IMPL_H_
#define CEF_LIBCEF_RENDERER_V8_IMPL_H_
#pragma once

#include <vector>

#include "include/cef_v8.h"
#include "libcef/common/tracker.h"

#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "v8/include/v8.h"

class CefTrackNode;
class GURL;

namespace blink {
class WebLocalFrame;
}

// Call after a V8 Isolate has been created and entered for the first time.
void CefV8IsolateCreated();

// Call before a V8 Isolate is exited and destroyed.
void CefV8IsolateDestroyed();

// Call to detach all handles associated with the specified context.
void CefV8ReleaseContext(v8::Local<v8::Context> context);

// Set the stack size for uncaught exceptions.
void CefV8SetUncaughtExceptionStackSize(int stack_size);

// Set attributes associated with a WebWorker thread.
void CefV8SetWorkerAttributes(int worker_id, const GURL& worker_url);

// Used to detach handles when the associated context is released.
class CefV8ContextState : public base::RefCounted<CefV8ContextState> {
 public:
  CefV8ContextState() : valid_(true) {}

  bool IsValid() { return valid_; }
  void Detach() {
    DCHECK(valid_);
    valid_ = false;
    track_manager_.DeleteAll();
  }

  void AddTrackObject(CefTrackNode* object) {
    DCHECK(valid_);
    track_manager_.Add(object);
  }

  void DeleteTrackObject(CefTrackNode* object) {
    DCHECK(valid_);
    track_manager_.Delete(object);
  }

 private:
  friend class base::RefCounted<CefV8ContextState>;

  ~CefV8ContextState() {}

  bool valid_;
  CefTrackManager track_manager_;
};

// Use this template in conjuction with RefCountedThreadSafe to ensure that a
// V8 object is deleted on the correct thread.
struct CefV8DeleteOnMessageLoopThread {
  template <typename T>
  static void Destruct(const T* x) {
    if (x->task_runner()->RunsTasksInCurrentSequence()) {
      delete x;
    } else {
      if (!x->task_runner()->DeleteSoon(FROM_HERE, x)) {
#if defined(UNIT_TEST)
        // Only logged under unit testing because leaks at shutdown
        // are acceptable under normal circumstances.
        LOG(ERROR) << "DeleteSoon failed on thread " << thread;
#endif  // UNIT_TEST
      }
    }
  }
};

// Base class for V8 Handle types.
class CefV8HandleBase
    : public base::RefCountedThreadSafe<CefV8HandleBase,
                                        CefV8DeleteOnMessageLoopThread> {
 public:
  // Returns true if there is no underlying context or if the underlying context
  // is valid.
  bool IsValid() const {
    return (!context_state_.get() || context_state_->IsValid());
  }

  bool BelongsToCurrentThread() const;

  v8::Isolate* isolate() const { return isolate_; }
  scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
    return task_runner_;
  }

 protected:
  friend class base::DeleteHelper<CefV8HandleBase>;
  friend class base::RefCountedThreadSafe<CefV8HandleBase,
                                          CefV8DeleteOnMessageLoopThread>;
  friend struct CefV8DeleteOnMessageLoopThread;

  // |context| is the context that owns this handle. If empty the current
  // context will be used.
  CefV8HandleBase(v8::Isolate* isolate, v8::Local<v8::Context> context);
  virtual ~CefV8HandleBase();

 protected:
  v8::Isolate* isolate_;
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  scoped_refptr<CefV8ContextState> context_state_;
};

// Template for V8 Handle types. This class is used to ensure that V8 objects
// are only released on the render thread.
template <typename v8class>
class CefV8Handle : public CefV8HandleBase {
 public:
  typedef v8::Local<v8class> handleType;
  typedef v8::Persistent<v8class> persistentType;

  CefV8Handle(v8::Isolate* isolate,
              v8::Local<v8::Context> context,
              handleType v)
      : CefV8HandleBase(isolate, context), handle_(isolate, v) {}

  handleType GetNewV8Handle() {
    DCHECK(IsValid());
    return handleType::New(isolate(), handle_);
  }

  persistentType& GetPersistentV8Handle() { return handle_; }

 protected:
  ~CefV8Handle() override { handle_.Reset(); }

  persistentType handle_;

  DISALLOW_COPY_AND_ASSIGN(CefV8Handle);
};

// Specialization for v8::Value with empty implementation to avoid incorrect
// usage.
template <>
class CefV8Handle<v8::Value> {};

class CefV8ContextImpl : public CefV8Context {
 public:
  CefV8ContextImpl(v8::Isolate* isolate, v8::Local<v8::Context> context);
  ~CefV8ContextImpl() override;

  CefRefPtr<CefTaskRunner> GetTaskRunner() override;
  bool IsValid() override;
  CefRefPtr<CefBrowser> GetBrowser() override;
  CefRefPtr<CefFrame> GetFrame() override;
  CefRefPtr<CefV8Value> GetGlobal() override;
  bool Enter() override;
  bool Exit() override;
  bool IsSame(CefRefPtr<CefV8Context> that) override;
  bool Eval(const CefString& code,
            const CefString& script_url,
            int start_line,
            CefRefPtr<CefV8Value>& retval,
            CefRefPtr<CefV8Exception>& exception) override;

  v8::Local<v8::Context> GetV8Context();
  blink::WebLocalFrame* GetWebFrame();

 private:
  typedef CefV8Handle<v8::Context> Handle;
  scoped_refptr<Handle> handle_;

  int enter_count_;
  std::unique_ptr<v8::MicrotasksScope> microtasks_scope_;

  IMPLEMENT_REFCOUNTING(CefV8ContextImpl);
  DISALLOW_COPY_AND_ASSIGN(CefV8ContextImpl);
};

class CefV8ValueImpl : public CefV8Value {
 public:
  explicit CefV8ValueImpl(v8::Isolate* isolate);
  CefV8ValueImpl(v8::Isolate* isolate,
                 v8::Local<v8::Context> context,
                 v8::Local<v8::Value> value);
  ~CefV8ValueImpl() override;

  // Used for initializing the CefV8ValueImpl. Should be called a single time
  // after the CefV8ValueImpl is created.
  void InitFromV8Value(v8::Local<v8::Context> context,
                       v8::Local<v8::Value> value);
  void InitUndefined();
  void InitNull();
  void InitBool(bool value);
  void InitInt(int32 value);
  void InitUInt(uint32 value);
  void InitDouble(double value);
  void InitDate(const CefTime& value);
  void InitString(CefString& value);
  void InitObject(v8::Local<v8::Value> value, CefTrackNode* tracker);

  // Creates a new V8 value for the underlying value or returns the existing
  // object handle.
  v8::Local<v8::Value> GetV8Value(bool should_persist);

  bool IsValid() override;
  bool IsUndefined() override;
  bool IsNull() override;
  bool IsBool() override;
  bool IsInt() override;
  bool IsUInt() override;
  bool IsDouble() override;
  bool IsDate() override;
  bool IsString() override;
  bool IsObject() override;
  bool IsArray() override;
  bool IsArrayBuffer() override;
  bool IsFunction() override;
  bool IsSame(CefRefPtr<CefV8Value> value) override;
  bool GetBoolValue() override;
  int32 GetIntValue() override;
  uint32 GetUIntValue() override;
  double GetDoubleValue() override;
  CefTime GetDateValue() override;
  CefString GetStringValue() override;
  bool IsUserCreated() override;
  bool HasException() override;
  CefRefPtr<CefV8Exception> GetException() override;
  bool ClearException() override;
  bool WillRethrowExceptions() override;
  bool SetRethrowExceptions(bool rethrow) override;
  bool HasValue(const CefString& key) override;
  bool HasValue(int index) override;
  bool DeleteValue(const CefString& key) override;
  bool DeleteValue(int index) override;
  CefRefPtr<CefV8Value> GetValue(const CefString& key) override;
  CefRefPtr<CefV8Value> GetValue(int index) override;
  bool SetValue(const CefString& key,
                CefRefPtr<CefV8Value> value,
                PropertyAttribute attribute) override;
  bool SetValue(int index, CefRefPtr<CefV8Value> value) override;
  bool SetValue(const CefString& key,
                AccessControl settings,
                PropertyAttribute attribute) override;
  bool GetKeys(std::vector<CefString>& keys) override;
  bool SetUserData(CefRefPtr<CefBaseRefCounted> user_data) override;
  CefRefPtr<CefBaseRefCounted> GetUserData() override;
  int GetExternallyAllocatedMemory() override;
  int AdjustExternallyAllocatedMemory(int change_in_bytes) override;
  int GetArrayLength() override;
  CefRefPtr<CefV8ArrayBufferReleaseCallback> GetArrayBufferReleaseCallback()
      override;
  bool NeuterArrayBuffer() override;
  CefString GetFunctionName() override;
  CefRefPtr<CefV8Handler> GetFunctionHandler() override;
  CefRefPtr<CefV8Value> ExecuteFunction(
      CefRefPtr<CefV8Value> object,
      const CefV8ValueList& arguments) override;
  CefRefPtr<CefV8Value> ExecuteFunctionWithContext(
      CefRefPtr<CefV8Context> context,
      CefRefPtr<CefV8Value> object,
      const CefV8ValueList& arguments) override;

 private:
  // Test for and record any exception.
  bool HasCaught(v8::Local<v8::Context> context, v8::TryCatch& try_catch);

  class Handle : public CefV8HandleBase {
   public:
    typedef v8::Local<v8::Value> handleType;
    typedef v8::Persistent<v8::Value> persistentType;

    Handle(v8::Isolate* isolate,
           v8::Local<v8::Context> context,
           handleType v,
           CefTrackNode* tracker);

    handleType GetNewV8Handle(bool should_persist);

    persistentType& GetPersistentV8Handle();

    void SetWeakIfNecessary();

   private:
    ~Handle() override;

   private:
    // Callbacks for weak persistent reference destruction.
    static void FirstWeakCallback(const v8::WeakCallbackInfo<Handle>& data);
    static void SecondWeakCallback(const v8::WeakCallbackInfo<Handle>& data);

    persistentType handle_;

    // For Object and Function types, we need to hold on to a reference to their
    // internal data or function handler objects that are reference counted.
    CefTrackNode* tracker_;

    // True if the handle needs to persist due to it being passed into V8.
    bool should_persist_;

    // True if the handle has been set as weak.
    bool is_set_weak_;

    DISALLOW_COPY_AND_ASSIGN(Handle);
  };

  v8::Isolate* isolate_;

  enum {
    TYPE_INVALID = 0,
    TYPE_UNDEFINED,
    TYPE_NULL,
    TYPE_BOOL,
    TYPE_INT,
    TYPE_UINT,
    TYPE_DOUBLE,
    TYPE_DATE,
    TYPE_STRING,
    TYPE_OBJECT,
  } type_;

  union {
    bool bool_value_;
    int32 int_value_;
    uint32 uint_value_;
    double double_value_;
    cef_time_t date_value_;
    cef_string_t string_value_;
  };

  // Used with Object, Function and Array types.
  scoped_refptr<Handle> handle_;

  CefRefPtr<CefV8Exception> last_exception_;
  bool rethrow_exceptions_;

  IMPLEMENT_REFCOUNTING(CefV8ValueImpl);
  DISALLOW_COPY_AND_ASSIGN(CefV8ValueImpl);
};

class CefV8StackTraceImpl : public CefV8StackTrace {
 public:
  CefV8StackTraceImpl(v8::Isolate* isolate, v8::Local<v8::StackTrace> handle);
  ~CefV8StackTraceImpl() override;

  bool IsValid() override;
  int GetFrameCount() override;
  CefRefPtr<CefV8StackFrame> GetFrame(int index) override;

 private:
  std::vector<CefRefPtr<CefV8StackFrame>> frames_;

  IMPLEMENT_REFCOUNTING(CefV8StackTraceImpl);
  DISALLOW_COPY_AND_ASSIGN(CefV8StackTraceImpl);
};

class CefV8StackFrameImpl : public CefV8StackFrame {
 public:
  CefV8StackFrameImpl(v8::Isolate* isolate, v8::Local<v8::StackFrame> handle);
  ~CefV8StackFrameImpl() override;

  bool IsValid() override;
  CefString GetScriptName() override;
  CefString GetScriptNameOrSourceURL() override;
  CefString GetFunctionName() override;
  int GetLineNumber() override;
  int GetColumn() override;
  bool IsEval() override;
  bool IsConstructor() override;

 private:
  CefString script_name_;
  CefString script_name_or_source_url_;
  CefString function_name_;
  int line_number_;
  int column_;
  bool is_eval_;
  bool is_constructor_;

  IMPLEMENT_REFCOUNTING(CefV8StackFrameImpl);
  DISALLOW_COPY_AND_ASSIGN(CefV8StackFrameImpl);
};

#endif  // CEF_LIBCEF_RENDERER_V8_IMPL_H_
