// Copyright 2020 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 INCLUDE_CPPGC_PERSISTENT_H_
#define INCLUDE_CPPGC_PERSISTENT_H_

#include <type_traits>

#include "cppgc/internal/persistent-node.h"
#include "cppgc/internal/pointer-policies.h"
#include "cppgc/source-location.h"
#include "cppgc/type-traits.h"
#include "cppgc/visitor.h"
#include "v8config.h"  // NOLINT(build/include_directory)

namespace cppgc {

class Visitor;

namespace internal {

class PersistentBase {
 protected:
  PersistentBase() = default;
  explicit PersistentBase(void* raw) : raw_(raw) {}

  void* GetValue() const { return raw_; }
  void SetValue(void* value) { raw_ = value; }

  PersistentNode* GetNode() const { return node_; }
  void SetNode(PersistentNode* node) { node_ = node; }

  // Performs a shallow clear which assumes that internal persistent nodes are
  // destroyed elsewhere.
  void ClearFromGC() const {
    raw_ = nullptr;
    node_ = nullptr;
  }

 private:
  mutable void* raw_ = nullptr;
  mutable PersistentNode* node_ = nullptr;

  friend class PersistentRegion;
};

// The basic class from which all Persistent classes are generated.
template <typename T, typename WeaknessPolicy, typename LocationPolicy,
          typename CheckingPolicy>
class BasicPersistent final : public PersistentBase,
                              public LocationPolicy,
                              private WeaknessPolicy,
                              private CheckingPolicy {
 public:
  using typename WeaknessPolicy::IsStrongPersistent;
  using PointeeType = T;

  // Null-state/sentinel constructors.
  BasicPersistent(  // NOLINT
      const SourceLocation& loc = SourceLocation::Current())
      : LocationPolicy(loc) {}

  BasicPersistent(std::nullptr_t,  // NOLINT
                  const SourceLocation& loc = SourceLocation::Current())
      : LocationPolicy(loc) {}

  BasicPersistent(  // NOLINT
      SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
      : PersistentBase(s), LocationPolicy(loc) {}

  // Raw value constructors.
  BasicPersistent(T* raw,  // NOLINT
                  const SourceLocation& loc = SourceLocation::Current())
      : PersistentBase(raw), LocationPolicy(loc) {
    if (!IsValid()) return;
    SetNode(WeaknessPolicy::GetPersistentRegion(GetValue())
                .AllocateNode(this, &BasicPersistent::Trace));
    this->CheckPointer(Get());
  }

  BasicPersistent(T& raw,  // NOLINT
                  const SourceLocation& loc = SourceLocation::Current())
      : BasicPersistent(&raw, loc) {}

  // Copy ctor.
  BasicPersistent(const BasicPersistent& other,
                  const SourceLocation& loc = SourceLocation::Current())
      : BasicPersistent(other.Get(), loc) {}

  // Heterogeneous ctor.
  template <typename U, typename OtherWeaknessPolicy,
            typename OtherLocationPolicy, typename OtherCheckingPolicy,
            typename = std::enable_if_t<std::is_base_of<T, U>::value>>
  BasicPersistent(  // NOLINT
      const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
                            OtherCheckingPolicy>& other,
      const SourceLocation& loc = SourceLocation::Current())
      : BasicPersistent(other.Get(), loc) {}

  // Move ctor. The heterogeneous move ctor is not supported since e.g.
  // persistent can't reuse persistent node from weak persistent.
  BasicPersistent(
      BasicPersistent&& other,
      const SourceLocation& loc = SourceLocation::Current()) noexcept
      : PersistentBase(std::move(other)), LocationPolicy(std::move(other)) {
    if (!IsValid()) return;
    GetNode()->UpdateOwner(this);
    other.SetValue(nullptr);
    other.SetNode(nullptr);
    this->CheckPointer(Get());
  }

  // Constructor from member.
  template <typename U, typename MemberBarrierPolicy,
            typename MemberWeaknessTag, typename MemberCheckingPolicy,
            typename = std::enable_if_t<std::is_base_of<T, U>::value>>
  BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy,  // NOLINT
                                        MemberWeaknessTag, MemberCheckingPolicy>
                      member,
                  const SourceLocation& loc = SourceLocation::Current())
      : BasicPersistent(member.Get(), loc) {}

  ~BasicPersistent() { Clear(); }

  // Copy assignment.
  BasicPersistent& operator=(const BasicPersistent& other) {
    return operator=(other.Get());
  }

  template <typename U, typename OtherWeaknessPolicy,
            typename OtherLocationPolicy, typename OtherCheckingPolicy,
            typename = std::enable_if_t<std::is_base_of<T, U>::value>>
  BasicPersistent& operator=(
      const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
                            OtherCheckingPolicy>& other) {
    return operator=(other.Get());
  }

  // Move assignment.
  BasicPersistent& operator=(BasicPersistent&& other) {
    if (this == &other) return *this;
    Clear();
    PersistentBase::operator=(std::move(other));
    LocationPolicy::operator=(std::move(other));
    if (!IsValid()) return *this;
    GetNode()->UpdateOwner(this);
    other.SetValue(nullptr);
    other.SetNode(nullptr);
    this->CheckPointer(Get());
    return *this;
  }

  // Assignment from member.
  template <typename U, typename MemberBarrierPolicy,
            typename MemberWeaknessTag, typename MemberCheckingPolicy,
            typename = std::enable_if_t<std::is_base_of<T, U>::value>>
  BasicPersistent& operator=(
      internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
                            MemberCheckingPolicy>
          member) {
    return operator=(member.Get());
  }

  BasicPersistent& operator=(T* other) {
    Assign(other);
    return *this;
  }

  BasicPersistent& operator=(std::nullptr_t) {
    Clear();
    return *this;
  }

  BasicPersistent& operator=(SentinelPointer s) {
    Assign(s);
    return *this;
  }

  explicit operator bool() const { return Get(); }
  operator T*() const { return Get(); }
  T* operator->() const { return Get(); }
  T& operator*() const { return *Get(); }

  // CFI cast exemption to allow passing SentinelPointer through T* and support
  // heterogeneous assignments between different Member and Persistent handles
  // based on their actual types.
  V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
    return static_cast<T*>(GetValue());
  }

  void Clear() { Assign(nullptr); }

  T* Release() {
    T* result = Get();
    Clear();
    return result;
  }

 private:
  static void Trace(Visitor* v, const void* ptr) {
    const auto* persistent = static_cast<const BasicPersistent*>(ptr);
    v->TraceRoot(*persistent, persistent->Location());
  }

  bool IsValid() const {
    // Ideally, handling kSentinelPointer would be done by the embedder. On the
    // other hand, having Persistent aware of it is beneficial since no node
    // gets wasted.
    return GetValue() != nullptr && GetValue() != kSentinelPointer;
  }

  void Assign(T* ptr) {
    if (IsValid()) {
      if (ptr && ptr != kSentinelPointer) {
        // Simply assign the pointer reusing the existing node.
        SetValue(ptr);
        this->CheckPointer(ptr);
        return;
      }
      WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
      SetNode(nullptr);
    }
    SetValue(ptr);
    if (!IsValid()) return;
    SetNode(WeaknessPolicy::GetPersistentRegion(GetValue())
                .AllocateNode(this, &BasicPersistent::Trace));
    this->CheckPointer(Get());
  }

  void ClearFromGC() const {
    if (IsValid()) {
      WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
      PersistentBase::ClearFromGC();
    }
  }

  friend class cppgc::Visitor;
};

template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
          typename LocationPolicy2, typename CheckingPolicy2>
bool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
                                      CheckingPolicy1>& p1,
                const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
                                      CheckingPolicy2>& p2) {
  return p1.Get() == p2.Get();
}

template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
          typename LocationPolicy2, typename CheckingPolicy2>
bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
                                      CheckingPolicy1>& p1,
                const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
                                      CheckingPolicy2>& p2) {
  return !(p1 == p2);
}

template <typename T1, typename PersistentWeaknessPolicy,
          typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
          typename T2, typename MemberWriteBarrierPolicy,
          typename MemberWeaknessTag, typename MemberCheckingPolicy>
bool operator==(const BasicPersistent<T1, PersistentWeaknessPolicy,
                                      PersistentLocationPolicy,
                                      PersistentCheckingPolicy>& p,
                BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
                            MemberCheckingPolicy>
                    m) {
  return p.Get() == m.Get();
}

template <typename T1, typename PersistentWeaknessPolicy,
          typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
          typename T2, typename MemberWriteBarrierPolicy,
          typename MemberWeaknessTag, typename MemberCheckingPolicy>
bool operator!=(const BasicPersistent<T1, PersistentWeaknessPolicy,
                                      PersistentLocationPolicy,
                                      PersistentCheckingPolicy>& p,
                BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
                            MemberCheckingPolicy>
                    m) {
  return !(p == m);
}

template <typename T1, typename MemberWriteBarrierPolicy,
          typename MemberWeaknessTag, typename MemberCheckingPolicy,
          typename T2, typename PersistentWeaknessPolicy,
          typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
                            MemberCheckingPolicy>
                    m,
                const BasicPersistent<T1, PersistentWeaknessPolicy,
                                      PersistentLocationPolicy,
                                      PersistentCheckingPolicy>& p) {
  return m.Get() == p.Get();
}

template <typename T1, typename MemberWriteBarrierPolicy,
          typename MemberWeaknessTag, typename MemberCheckingPolicy,
          typename T2, typename PersistentWeaknessPolicy,
          typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
                            MemberCheckingPolicy>
                    m,
                const BasicPersistent<T1, PersistentWeaknessPolicy,
                                      PersistentLocationPolicy,
                                      PersistentCheckingPolicy>& p) {
  return !(m == p);
}

template <typename T, typename LocationPolicy, typename CheckingPolicy>
struct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy,
                              CheckingPolicy>> : std::true_type {};
}  // namespace internal

/**
 * Persistent is a way to create a strong pointer from an off-heap object to
 * another on-heap object. As long as the Persistent handle is alive the GC will
 * keep the object pointed to alive. The Persistent handle is always a GC root
 * from the point of view of the GC. Persistent must be constructed and
 * destructed in the same thread.
 */
template <typename T>
using Persistent =
    internal::BasicPersistent<T, internal::StrongPersistentPolicy>;

/**
 * WeakPersistent is a way to create a weak pointer from an off-heap object to
 * an on-heap object. The pointer is automatically cleared when the pointee gets
 * collected. WeakPersistent must be constructed and destructed in the same
 * thread.
 */
template <typename T>
using WeakPersistent =
    internal::BasicPersistent<T, internal::WeakPersistentPolicy>;

}  // namespace cppgc

#endif  // INCLUDE_CPPGC_PERSISTENT_H_
