/*
 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <wtf/DumbPtrTraits.h>
#include <wtf/HashCountedSet.h>
#include <wtf/RefPtr.h>

namespace WebCore {

class Node;

class GCReachableRefMap {
public:
    static inline bool contains(Node& node) { return map().contains(&node); }
    static inline void add(Node& node) { map().add(&node); }
    static inline void remove(Node& node) { map().remove(&node); }

private:
    static HashCountedSet<Node*>& map();
};

template <typename T, typename = std::enable_if_t<std::is_same<T, typename std::remove_const<T>::type>::value>>
class GCReachableRef {
    WTF_MAKE_NONCOPYABLE(GCReachableRef);
public:

    template<typename = std::enable_if_t<std::is_base_of<Node, T>::value>>
    GCReachableRef(T& object)
        : m_ptr(&object)
    {
        GCReachableRefMap::add(*m_ptr);
    }

    ~GCReachableRef()
    {
        if (m_ptr)
            GCReachableRefMap::remove(*m_ptr);
    }

    GCReachableRef(GCReachableRef&& other)
        : m_ptr(WTFMove(other.m_ptr))
    {
    }

    T* operator->() const { return &get(); }
    T* ptr() const RETURNS_NONNULL { return &get(); }
    T& get() const { ASSERT(m_ptr); return *m_ptr; }
    operator T&() const { return get(); }
    bool operator!() const { return !get(); }

    // Hash table deleted values, which are only constructed and never copied or destroyed.
    GCReachableRef(WTF::HashTableDeletedValueType)
        : m_ptr(RefPtr<T>::hashTableDeletedValue())
    { }
    bool isHashTableDeletedValue() const { return m_ptr.isHashTableDeletedValue(); }

    GCReachableRef(WTF::HashTableEmptyValueType)
        : m_ptr(nullptr)
    { }
    bool isHashTableEmptyValue() const { return !m_ptr; }

    const T* ptrAllowingHashTableEmptyValue() const { ASSERT(m_ptr || isHashTableEmptyValue()); return m_ptr.get(); }
    T* ptrAllowingHashTableEmptyValue() { ASSERT(m_ptr || isHashTableEmptyValue()); return m_ptr.get(); }

    void assignToHashTableEmptyValue(GCReachableRef&& reference)
    {
        ASSERT(!m_ptr);
        m_ptr = WTFMove(reference.m_ptr);
        ASSERT(m_ptr);
    }

private:
    RefPtr<T> m_ptr;
};

} // namespace WebCore

namespace WTF {

template<typename P> struct HashTraits<WebCore::GCReachableRef<P>> : SimpleClassHashTraits<WebCore::GCReachableRef<P>> {
    static const bool emptyValueIsZero = true;
    static WebCore::GCReachableRef<P> emptyValue() { return HashTableEmptyValue; }

    template <typename>
    static void constructEmptyValue(WebCore::GCReachableRef<P>& slot)
    {
        new (NotNull, std::addressof(slot)) WebCore::GCReachableRef<P>(HashTableEmptyValue);
    }

    static const bool hasIsEmptyValueFunction = true;
    static bool isEmptyValue(const WebCore::GCReachableRef<P>& value) { return value.isHashTableEmptyValue(); }

    static void assignToEmpty(WebCore::GCReachableRef<P>& emptyValue, WebCore::GCReachableRef<P>&& newValue)
    {
        ASSERT(isEmptyValue(emptyValue));
        emptyValue.assignToHashTableEmptyValue(WTFMove(newValue));
    }

    typedef P* PeekType;
    static PeekType peek(const Ref<P>& value) { return const_cast<PeekType>(value.ptrAllowingHashTableEmptyValue()); }
    static PeekType peek(P* value) { return value; }

    typedef Optional<Ref<P>> TakeType;
    static TakeType take(Ref<P>&& value) { return isEmptyValue(value) ? WTF::nullopt : Optional<Ref<P>>(WTFMove(value)); }
};

template <typename T, typename U>
struct GetPtrHelper<WebCore::GCReachableRef<T, U>> {
    typedef T* PtrType;
    static T* getPtr(const WebCore::GCReachableRef<T, U>& reference) { return const_cast<T*>(reference.ptr()); }
};

template <typename T, typename U>
struct IsSmartPtr<WebCore::GCReachableRef<T, U>> {
    static const bool value = true;
};

template<typename P> struct PtrHash<WebCore::GCReachableRef<P>> : PtrHashBase<WebCore::GCReachableRef<P>, IsSmartPtr<WebCore::GCReachableRef<P>>::value> {
    static const bool safeToCompareToEmptyOrDeleted = false;
};

template<typename P> struct DefaultHash<WebCore::GCReachableRef<P>> {
    typedef PtrHash<WebCore::GCReachableRef<P>> Hash;
};

} // namespace WTF

