// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COMMON_REFBASE_H_
#define COMMON_REFBASE_H_

#include "common/Assert.h"
#include "common/Compiler.h"

#include <type_traits>
#include <utility>

// A common class for various smart-pointers acting on referenceable/releasable pointer-like
// objects. Logic for each specialization can be customized using a Traits type that looks
// like the following:
//
//   struct {
//      static constexpr T kNullValue = ...;
//      static void Reference(T value) { ... }
//      static void Release(T value) { ... }
//   };
//
// RefBase supports
template <typename T, typename Traits>
class RefBase {
  public:
    // Default constructor and destructor.
    RefBase() : mValue(Traits::kNullValue) {
    }

    ~RefBase() {
        Release(mValue);
    }

    // Constructors from nullptr.
    constexpr RefBase(std::nullptr_t) : RefBase() {
    }

    RefBase<T, Traits>& operator=(std::nullptr_t) {
        Set(Traits::kNullValue);
        return *this;
    }

    // Constructors from a value T.
    RefBase(T value) : mValue(value) {
        Reference(value);
    }

    RefBase<T, Traits>& operator=(const T& value) {
        Set(value);
        return *this;
    }

    // Constructors from a RefBase<T>
    RefBase(const RefBase<T, Traits>& other) : mValue(other.mValue) {
        Reference(other.mValue);
    }

    RefBase<T, Traits>& operator=(const RefBase<T, Traits>& other) {
        Set(other.mValue);
        return *this;
    }

    RefBase(RefBase<T, Traits>&& other) {
        mValue = other.Detach();
    }

    RefBase<T, Traits>& operator=(RefBase<T, Traits>&& other) {
        if (&other != this) {
            Release(mValue);
            mValue = other.Detach();
        }
        return *this;
    }

    // Constructors from a RefBase<U>. Note that in the *-assignment operators this cannot be the
    // same as `other` because overload resolution rules would have chosen the *-assignement
    // operators defined with `other` == RefBase<T, Traits>.
    template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
    RefBase(const RefBase<U, UTraits>& other) : mValue(other.mValue) {
        Reference(other.mValue);
    }

    template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
    RefBase<T, Traits>& operator=(const RefBase<U, UTraits>& other) {
        Set(other.mValue);
        return *this;
    }

    template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
    RefBase(RefBase<U, UTraits>&& other) {
        mValue = other.Detach();
    }

    template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
    RefBase<T, Traits>& operator=(RefBase<U, UTraits>&& other) {
        Release(mValue);
        mValue = other.Detach();
        return *this;
    }

    // Comparison operators.
    bool operator==(const T& other) const {
        return mValue == other;
    }

    bool operator!=(const T& other) const {
        return mValue != other;
    }

    const T operator->() const {
        return mValue;
    }
    T operator->() {
        return mValue;
    }

    // Smart pointer methods.
    const T& Get() const {
        return mValue;
    }
    T& Get() {
        return mValue;
    }

    T Detach() DAWN_NO_DISCARD {
        T value{std::move(mValue)};
        mValue = Traits::kNullValue;
        return value;
    }

    void Acquire(T value) {
        Release(mValue);
        mValue = value;
    }

    T* InitializeInto() DAWN_NO_DISCARD {
        ASSERT(mValue == Traits::kNullValue);
        return &mValue;
    }

  private:
    // Friend is needed so that instances of RefBase<U> can call Reference and Release on
    // RefBase<T>.
    template <typename U, typename UTraits>
    friend class RefBase;

    static void Reference(T value) {
        if (value != Traits::kNullValue) {
            Traits::Reference(value);
        }
    }
    static void Release(T value) {
        if (value != Traits::kNullValue) {
            Traits::Release(value);
        }
    }

    void Set(T value) {
        if (mValue != value) {
            // Ensure that the new value is referenced before the old is released to prevent any
            // transitive frees that may affect the new value.
            Reference(value);
            Release(mValue);
            mValue = value;
        }
    }

    T mValue;
};

#endif  // COMMON_REFBASE_H_
