/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QT3DCORE_QABSTRACTRESOURCESMANAGER_H
#define QT3DCORE_QABSTRACTRESOURCESMANAGER_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of other Qt classes.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtCore/QHash>
#include <QtCore/QMutex>
#include <QtCore/QReadLocker>
#include <QtCore/QReadWriteLock>
#include <QtCore/QtGlobal>
#include <limits>

#include <Qt3DCore/private/qhandle_p.h>
#include <Qt3DCore/private/qt3dcore_global_p.h>

// Silence complaints about unreferenced local variables in
// ArrayAllocatingPolicy::deallocateBuckets() when the compiler
// inlines the call to the dtor and it is empty. Default warning
// setting re-enabled at bottom of this file
#if defined(Q_CC_MSVC)
#pragma warning(disable : 4189)
#endif

QT_BEGIN_NAMESPACE

namespace Qt3DCore {

template <class Host>
struct NonLockingPolicy
{
    struct ReadLocker
    {
        ReadLocker(const NonLockingPolicy*) {}
        void unlock() {}
        void relock() {}
    };

    struct WriteLocker
    {
        WriteLocker(const NonLockingPolicy*) {}
        void unlock() {}
        void relock() {}
    };

    struct Locker
    {
        Locker(const NonLockingPolicy*) {}
        void unlock() {}
        void relock() {}
    };
};

template <class Host>
class ObjectLevelLockingPolicy
{
public :
    ObjectLevelLockingPolicy()
    {}

    class ReadLocker
    {
    public:
        ReadLocker(const ObjectLevelLockingPolicy *host)
            : m_locker(&host->m_readWritelock)
        { }

        void unlock()
        {
            m_locker.unlock();
        }

        void relock()
        {
            m_locker.relock();
        }

    private:
        QReadLocker m_locker;
    };

    class WriteLocker
    {
    public:
        WriteLocker(const ObjectLevelLockingPolicy *host)
            : m_locker(&host->m_readWritelock)
        { }

        void unlock()
        {
            m_locker.unlock();
        }

        void relock()
        {
            m_locker.relock();
        }

    private:
        QWriteLocker m_locker;
    };

    class Locker
    {
    public:
        Locker(const ObjectLevelLockingPolicy *host)
            : m_locker(&host->m_lock)
        { }

        void unlock()
        {
            m_locker.unlock();
        }

        void relock()
        {
            m_locker.relock();
        }

    private:
        QMutexLocker m_locker;
    };

private:
    friend class Locker;
    friend class ReadLocker;
    friend class WriteLocker;
    mutable QReadWriteLock m_readWritelock;
    mutable QMutex m_lock;
};

template <typename T>
struct QResourceInfo
{
    enum
    {
        needsCleanup = false
    };
};

template <>
struct QResourceInfo<void>
{
    enum
    {
        needsCleanup = false
    };
};

enum
{
    Q_REQUIRES_CLEANUP = 0
};

#define Q_DECLARE_RESOURCE_INFO(TYPE, FLAGS) \
    namespace Qt3DCore { \
    template<> \
    struct QResourceInfo<TYPE > \
{ \
    enum \
{ \
    needsCleanup = ((FLAGS & Q_REQUIRES_CLEANUP) == 0) \
}; \
}; \
} // namespace Qt3DCore

template <int v>
struct Int2Type
{
    enum
    {
        value = v
    };
};

template<typename T>
class QHandleData : public QHandle<T>::Data
{
public:
    T data;
};

template<typename T>
inline T *QHandle<T>::operator->() const { return (d && counter == d->counter) ? &static_cast<QHandleData<T> *>(d)->data : nullptr; }
template<typename T>
inline T *QHandle<T>::data() const { return (d && counter == d->counter) ? &static_cast<QHandleData<T> *>(d)->data : nullptr; }


class Q_3DCORE_PRIVATE_EXPORT AlignedAllocator
{
public:
    static void *allocate(uint size);
    static void release(void *p);
};

template <typename T>
class ArrayAllocatingPolicy
{
public:
    typedef QHandleData<T> HandleData;
    typedef QHandle<T> Handle;
    ArrayAllocatingPolicy()
    {
    }

    ~ArrayAllocatingPolicy()
    {
        m_activeHandles.clear();
        deallocateBuckets();
    }

    Handle allocateResource()
    {
        if (!freeList)
            allocateBucket();
        typename Handle::Data *d = freeList;
        freeList = freeList->nextFree;
        d->counter = allocCounter;
        allocCounter += 2; // ensure this will never clash with a pointer in nextFree by keeping the lowest bit set
        Handle handle(d);
        m_activeHandles.push_back(handle);
        return handle;
    }

    void releaseResource(const Handle &handle)
    {
        m_activeHandles.removeOne(handle);
        typename Handle::Data *d = handle.data_ptr();
        d->nextFree = freeList;
        freeList = d;
        performCleanup(&static_cast<QHandleData<T> *>(d)->data, Int2Type<QResourceInfo<T>::needsCleanup>());
    }

    T *data(Handle h)
    {
        return h.operator->();
    }

    void for_each(std::function<void(T*)> f)
    {
        Bucket *b = firstBucket;
        while (b) {
            for (int idx = 0; idx < Bucket::NumEntries; ++idx) {
                T *t = &b->data[idx].data;
                f(t);
            }
            b = b->header.next;
        }
    }

    int count() const { return m_activeHandles.size(); }
    QVector<Handle> activeHandles() const { return m_activeHandles; }

private:
    Q_DISABLE_COPY(ArrayAllocatingPolicy)
    struct Bucket
    {
        struct Header
        {
            Bucket *next;
        } header;
        enum {
            Size = 4096,
            NumEntries = (Size - sizeof(Header)) / sizeof(HandleData)
        };
        HandleData data[NumEntries];
    };

    Bucket *firstBucket = 0;
    QVector<Handle > m_activeHandles;
    typename Handle::Data *freeList = 0;
    int allocCounter = 1;

    void allocateBucket()
    {
        // no free handle, allocate a new
        // allocate aligned memory
        Bucket *b = static_cast<Bucket *>(AlignedAllocator::allocate(sizeof(Bucket)));

        // placement new
        new (b) Bucket;

        b->header.next = firstBucket;
        firstBucket = b;
        for (int i = 0; i < Bucket::NumEntries - 1; ++i) {
            b->data[i].nextFree = &b->data[i + 1];
        }
        b->data[Bucket::NumEntries - 1].nextFree = nullptr;
        freeList = &b->data[0];
    }

    void deallocateBuckets()
    {
        Bucket *b = firstBucket;
        while (b) {
            Bucket *n = b->header.next;
            // Call dtor explicitly
            b->~Bucket();
            // Release aligned memory
            AlignedAllocator::release(b);
            b = n;
        }
    }

    void performCleanup(T *r, Int2Type<true>)
    {
        r->cleanup();
    }

    void performCleanup(T *, Int2Type<false>)
    {}

};

#ifndef QT_NO_DEBUG_STREAM
template <typename ValueType, typename KeyType,
          template <class> class LockingPolicy
          >
class QResourceManager;

template <typename ValueType, typename KeyType,
          template <class> class LockingPolicy = NonLockingPolicy
          >
QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, LockingPolicy> &manager);
#endif

template <typename ValueType, typename KeyType,
          template <class> class LockingPolicy = NonLockingPolicy
          >
class QResourceManager
        : public ArrayAllocatingPolicy<ValueType>
        , public LockingPolicy< QResourceManager<ValueType, KeyType, LockingPolicy> >
{
public:
    typedef ArrayAllocatingPolicy<ValueType> Allocator;
    typedef QHandle<ValueType> Handle;

    QResourceManager() :
        Allocator()
    {
    }

    ~QResourceManager()
    {}

    Handle acquire()
    {
        typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
        return Allocator::allocateResource();
    }

    ValueType* data(const Handle &handle)
    {
        return handle.operator->();
    }

    void release(const Handle &handle)
    {
        typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
        Allocator::releaseResource(handle);
    }

    bool contains(const KeyType &id) const
    {
        typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
        return m_keyToHandleMap.contains(id);
    }

    Handle getOrAcquireHandle(const KeyType &id)
    {
        typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
        Handle handle = m_keyToHandleMap.value(id);
        if (handle.isNull()) {
            lock.unlock();
            typename LockingPolicy<QResourceManager>::WriteLocker writeLock(this);
            // Test that the handle hasn't been set (in the meantime between the read unlock and the write lock)
            Handle &handleToSet = m_keyToHandleMap[id];
            if (handleToSet.isNull()) {
                handleToSet = Allocator::allocateResource();
            }
            return handleToSet;
        }
        return handle;
    }

    Handle lookupHandle(const KeyType &id)
    {
        typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
        return m_keyToHandleMap.value(id);
    }

    ValueType *lookupResource(const KeyType &id)
    {
        ValueType* ret = nullptr;
        {
            typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
            Handle handle = m_keyToHandleMap.value(id);
            if (!handle.isNull())
                ret = Allocator::data(handle);
        }
        return ret;
    }

    ValueType *getOrCreateResource(const KeyType &id)
    {
        const Handle handle = getOrAcquireHandle(id);
        return handle.operator->();
    }

    void releaseResource(const KeyType &id)
    {
        typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
        Handle handle = m_keyToHandleMap.take(id);
        if (!handle.isNull())
            Allocator::releaseResource(handle);
    }

protected:
    QHash<KeyType, Handle > m_keyToHandleMap;

private:
    friend QDebug operator<< <>(QDebug dbg, const QResourceManager<ValueType, KeyType, LockingPolicy> &manager);
};

#ifndef QT_NO_DEBUG_STREAM
template <typename ValueType, typename KeyType,
          template <class> class LockingPolicy
          >
QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, LockingPolicy> &manager)
{
    QDebugStateSaver saver(dbg);
    dbg << "Contains" << manager.count() << "items" << endl;

    dbg << "Key to Handle Map:" << endl;
    const auto end = manager.m_keyToHandleMap.cend();
    for (auto it = manager.m_keyToHandleMap.cbegin(); it != end; ++it)
        dbg << "QNodeId =" << it.key() << "Handle =" << it.value() << endl;

//    dbg << "Resources:" << endl;
//    dbg << manager.m_handleManager;
    return dbg;
}
#endif

}// Qt3D

QT_END_NAMESPACE

#if defined(Q_CC_MSVC)
#pragma warning(default : 4189)
#endif

#endif // QT3DCORE_QABSTRACTRESOURCESMANAGER_H
