// Copyright (c) 2022 The Chromium 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 QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_

#include <atomic>
#include <memory>

#include "absl/base/attributes.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace quiche {

class QUICHE_EXPORT_PRIVATE QuicheReferenceCountedImpl {
 public:
  virtual ~QuicheReferenceCountedImpl() { QUICHE_DCHECK_EQ(ref_count_, 0); }

  void AddReference() { ref_count_.fetch_add(1, std::memory_order_relaxed); }

  // Returns true if the objects needs to be deleted.
  ABSL_MUST_USE_RESULT bool RemoveReference() {
    int new_count = ref_count_.fetch_sub(1, std::memory_order_acq_rel) - 1;
    QUICHE_DCHECK_GE(new_count, 0);
    return new_count == 0;
  }

  bool HasUniqueReference() const {
    return ref_count_.load(std::memory_order_acquire) == 1;
  }

 private:
  std::atomic<int> ref_count_ = 1;
};

template <class T>
class QUICHE_NO_EXPORT QuicheReferenceCountedPointerImpl {
 public:
  QuicheReferenceCountedPointerImpl() = default;
  ~QuicheReferenceCountedPointerImpl() { RemoveReference(); }

  // Constructor from raw pointer |p|. This guarantees that the reference count
  // of *p is 1. This should be only called when a new object is created.
  explicit QuicheReferenceCountedPointerImpl(T* p) : object_(p) {
    if (p != nullptr) {
      QUICHE_DCHECK(p->HasUniqueReference());
    }
  }

  explicit QuicheReferenceCountedPointerImpl(std::nullptr_t)
      : object_(nullptr) {}

  // Copy and copy conversion constructors.
  QuicheReferenceCountedPointerImpl(
      const QuicheReferenceCountedPointerImpl& other) {
    AssignObject(other.get());
    AddReference();
  }
  template <typename U>
  QuicheReferenceCountedPointerImpl(  // NOLINT
      const QuicheReferenceCountedPointerImpl<U>& other) {
    AssignObject(other.get());
    AddReference();
  }

  // Move constructors.
  QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl&& other) {
    object_ = other.object_;
    other.object_ = nullptr;
  }
  template <typename U>
  QuicheReferenceCountedPointerImpl(
      QuicheReferenceCountedPointerImpl<U>&& other) {  // NOLINT
    // We can't access other.object_ since other has different T and object_ is
    // private.
    object_ = other.get();
    AddReference();
    other = nullptr;
  }

  // Copy assignments.
  QuicheReferenceCountedPointerImpl& operator=(
      const QuicheReferenceCountedPointerImpl& other) {
    AssignObject(other.object_);
    AddReference();
    return *this;
  }
  template <typename U>
  QuicheReferenceCountedPointerImpl<T>& operator=(
      const QuicheReferenceCountedPointerImpl<U>& other) {
    AssignObject(other.object_);
    AddReference();
    return *this;
  }

  // Move assignments.
  QuicheReferenceCountedPointerImpl& operator=(
      QuicheReferenceCountedPointerImpl&& other) {
    AssignObject(other.object_);
    other.object_ = nullptr;
    return *this;
  }
  template <typename U>
  QuicheReferenceCountedPointerImpl<T>& operator=(
      QuicheReferenceCountedPointerImpl<U>&& other) {
    AssignObject(other.get());
    AddReference();
    other = nullptr;
    return *this;
  }

  T& operator*() const { return *object_; }
  T* operator->() const { return object_; }

  explicit operator bool() const { return object_ != nullptr; }

  // Assignment operator on raw pointer.  Behaves similar to the raw pointer
  // constructor.
  QuicheReferenceCountedPointerImpl<T>& operator=(T* p) {
    AssignObject(p);
    if (p != nullptr) {
      QUICHE_DCHECK(p->HasUniqueReference());
    }
    return *this;
  }

  // Returns the raw pointer with no change in reference count.
  T* get() const { return object_; }

  // Comparisons against same type.
  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
                         const QuicheReferenceCountedPointerImpl& b) {
    return a.get() == b.get();
  }
  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
                         const QuicheReferenceCountedPointerImpl& b) {
    return a.get() != b.get();
  }

  // Comparisons against nullptr.
  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
                         std::nullptr_t) {
    return a.get() == nullptr;
  }
  friend bool operator==(std::nullptr_t,
                         const QuicheReferenceCountedPointerImpl& b) {
    return nullptr == b.get();
  }
  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
                         std::nullptr_t) {
    return a.get() != nullptr;
  }
  friend bool operator!=(std::nullptr_t,
                         const QuicheReferenceCountedPointerImpl& b) {
    return nullptr != b.get();
  }

 private:
  void AddReference() {
    if (object_ == nullptr) {
      return;
    }
    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
    implicitly_cast_object->AddReference();
  }

  void RemoveReference() {
    if (object_ == nullptr) {
      return;
    }
    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
    if (implicitly_cast_object->RemoveReference()) {
      delete implicitly_cast_object;
    }
    object_ = nullptr;
  }

  void AssignObject(T* new_object) {
    RemoveReference();
    object_ = new_object;
  }

  T* object_ = nullptr;
};

}  // namespace quiche

#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
