/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrRefCnt_DEFINED
#define GrRefCnt_DEFINED

#include "include/core/SkRefCnt.h"

 /** Check if the argument is non-null, and if so, call obj->addCommandBufferUsage() and return obj.
 */
template <typename T> static inline T* GrSafeRefCBUsage(T* obj) {
    if (obj) {
        obj->addCommandBufferUsage();
    }
    return obj;
}

/** Check if the argument is non-null, and if so, call obj->removeCommandBufferUsage()
 */
template <typename T> static inline void GrSafeUnrefCBUsage(T* obj) {
    if (obj) {
        obj->removeCommandBufferUsage();
    }
}

/**
 * Shared pointer class to wrap classes that support a addCommandBufferUsage() and
 * removeCommandBufferUsage() interface.
 *
 * This class supports copying, moving, and assigning an sk_sp into it. In general these commands do
 * not modify the sk_sp at all but just call addCommandBufferUsage() on the underlying object.
 *
 * This class is designed to be used by GrGpuResources that need to track when they are in use on
 * gpu (usually via a command buffer) separately from tracking if there are any current logical
 * usages in Ganesh. This allows for a scratch GrGpuResource to be reused for new draw calls even
 * if it is in use on the GPU.
 */
template <typename T> class gr_cb {
public:
    using element_type = T;

    constexpr gr_cb() : fPtr(nullptr) {}
    constexpr gr_cb(std::nullptr_t) : fPtr(nullptr) {}

    /**
     * Shares the underlying object by calling addCommandBufferUsage(), so that both the argument
     * and the newly created gr_cb both have a reference to it.
     */
    gr_cb(const gr_cb<T>& that) : fPtr(GrSafeRefCBUsage(that.get())) {}

    gr_cb(const sk_sp<T>& that) : fPtr(GrSafeRefCBUsage(that.get())) {}

    /**
     * Move the underlying object from the argument to the newly created gr_cb. Afterwards only
     * the new gr_cb will have a reference to the object, and the argument will point to null.
     * No call to addCommandBufferUsage() or removeCommandBufferUsage() will be made.
     */
    gr_cb(gr_cb<T>&& that) : fPtr(that.release()) {}

    /**
     * Copies the underlying object pointer from the argument to the gr_cb. It will then call
     * addCommandBufferUsage() on the new object.
     */
    gr_cb(sk_sp<T>&& that) : fPtr(GrSafeRefCBUsage(that.get())) {}

    /**
     * Calls removeCommandBufferUsage() on the underlying object pointer.
     */
    ~gr_cb() {
        GrSafeUnrefCBUsage(fPtr);
        SkDEBUGCODE(fPtr = nullptr);
    }

    gr_cb<T>& operator=(std::nullptr_t) {
        this->reset();
        return *this;
    }

    /**
     * Shares the underlying object referenced by the argument by calling addCommandBufferUsage() on
     * it. If this gr_cb previously had a reference to an object (i.e. not null) it will call
     * removeCommandBufferUsage() on thatobject.
     */
    gr_cb<T>& operator=(const gr_cb<T>& that) {
        if (this != &that) {
            this->reset(GrSafeRefCBUsage(that.get()));
        }
        return *this;
    }

    /**
     * Copies the underlying object pointer from the argument to the gr_cb. If the gr_cb previously
     * held a reference to another object, removeCommandBufferUsage() will be called on that object.
     * It will then call addCommandBufferUsage() on the new object.
     */
    gr_cb<T>& operator=(const sk_sp<T>& that) {
        this->reset(GrSafeRefCBUsage(that.get()));
        return *this;
    }

    /**
     * Move the underlying object from the argument to the gr_cb. If the gr_cb previously held
     * a reference to another object, removeCommandBufferUsage() will be called on that object. No
     * call to addCommandBufferUsage() will be made.
     */
    gr_cb<T>& operator=(gr_cb<T>&& that) {
        this->reset(that.release());
        return *this;
    }

    /**
     * Copies the underlying object pointer from the argument to the gr_cb. If the gr_cb previously
     * held a reference to another object, removeCommandBufferUsage() will be called on that object.
     * It will then call addCommandBufferUsage() on the new object.
     */
    gr_cb<T>& operator=(sk_sp<T>&& that) {
        this->reset(GrSafeRefCBUsage(that.get()));
        return *this;
    }

    T& operator*() const {
        SkASSERT(this->get() != nullptr);
        return *this->get();
    }

    explicit operator bool() const { return this->get() != nullptr; }

    T* get() const { return fPtr; }
    T* operator->() const { return fPtr; }

private:
    /**
     * Adopt the new bare pointer, and call removeCommandBufferUsage() on any previously held object
     * (if not null). No call to addCommandBufferUsage() will be made.
     */
    void reset(T* ptr = nullptr) {
        T* oldPtr = fPtr;
        fPtr = ptr;
        GrSafeUnrefCBUsage(oldPtr);
    }

    /**
     * Return the bare pointer, and set the internal object pointer to nullptr.
     * The caller must assume ownership of the object, and manage its reference count directly.
     * No call to removeCommandBufferUsage() will be made.
     */
    T* SK_WARN_UNUSED_RESULT release() {
        T* ptr = fPtr;
        fPtr = nullptr;
        return ptr;
    }

    T* fPtr;
};

template <typename T, typename U> inline bool operator==(const gr_cb<T>& a, const gr_cb<U>& b) {
    return a.get() == b.get();
}
template <typename T> inline bool operator==(const gr_cb<T>& a, std::nullptr_t) /*noexcept*/ {
    return !a;
}
template <typename T> inline bool operator==(std::nullptr_t, const gr_cb<T>& b) /*noexcept*/ {
    return !b;
}

template <typename T, typename U> inline bool operator!=(const gr_cb<T>& a, const gr_cb<U>& b) {
    return a.get() != b.get();
}
template <typename T> inline bool operator!=(const gr_cb<T>& a, std::nullptr_t) /*noexcept*/ {
    return static_cast<bool>(a);
}
template <typename T> inline bool operator!=(std::nullptr_t, const gr_cb<T>& b) /*noexcept*/ {
    return static_cast<bool>(b);
}

#endif
