// Copyright (C) 2019 The Android Open Source Project
//
// 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.
#pragma once

#include "base/Lookup.h"
#include "base/Optional.h"

#include <functional>
#include <unordered_map>
#include <vector>

#include <inttypes.h>
#include <stdio.h>

#define ENTITY_MANAGER_DEBUG 0

#if ENTITY_MANAGER_DEBUG

#define EM_DBG(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);

#else
#define EM_DBG(...)
#endif

#define INVALID_ENTITY_HANDLE 0
#define INVALID_COMPONENT_HANDLE 0

namespace android {
namespace base {

// EntityManager: A way to represent an abstrat space of objects with handles.
// Each handle is associated with data of type Item for quick access from handles to data.
// Otherwise, entity data is spread through ComponentManagers.
template<size_t indexBits,
         size_t generationBits,
         size_t typeBits,
         class Item>
class EntityManager {
public:

    static_assert(64 == (indexBits + generationBits + typeBits),
                  "bits of index, generation, and type must add to 64");

    using EntityHandle = uint64_t;
    using IteratorFunc = std::function<void(bool live, EntityHandle h, Item& item)>;
    using ConstIteratorFunc = std::function<void(bool live, EntityHandle h, const Item& item)>;

    static size_t getHandleIndex(EntityHandle h) {
        return static_cast<size_t>(h & ((1ULL << indexBits) - 1ULL));
    }

    static size_t getHandleGeneration(EntityHandle h) {
        return static_cast<size_t>(
            (h >> indexBits) &
            ((1ULL << generationBits) - 1ULL));
    }

    static size_t getHandleType(EntityHandle h) {
        return static_cast<size_t>(
            (h >> (indexBits + generationBits)) &
            ((1ULL << typeBits) - 1ULL));
        return h & ((1ULL << indexBits) - 1ULL);
    }

    static EntityHandle makeHandle(
        size_t index,
        size_t generation,
        size_t type) {
        EntityHandle res = index;
        res |= generation << indexBits;
        res |= type << (indexBits + generationBits);
        return res;
    }

    static EntityHandle withIndex(EntityHandle h, size_t i) {
        return makeHandle(i, getHandleGeneration(h), getHandleType(h));
    }

    static EntityHandle withGeneration(EntityHandle h, size_t nextGen) {
        return makeHandle(getHandleIndex(h), nextGen, getHandleType(h));
    }

    static EntityHandle withType(EntityHandle h, size_t newType) {
        return makeHandle(getHandleIndex(h), getHandleGeneration(h), newType);
    }

    EntityManager() : EntityManager(0) { }

    EntityManager(size_t initialItems) :
        mEntries(initialItems),
        mFirstFreeIndex(0),
        mLiveEntries(0) {
        reserve(initialItems);
    }

    ~EntityManager() { clear(); }

    struct EntityEntry {
        EntityHandle handle = 0;
        size_t nextFreeIndex = 0;
        // 0 is a special generation for brand new entries
        // that are not used yet
        size_t liveGeneration = 1;
        Item item;
    };

	void clear() {
		reserve(mEntries.size());
        mFirstFreeIndex = 0;
        mLiveEntries = 0;
    }

    size_t nextFreeIndex() const {
        return mFirstFreeIndex;
    }

    EntityHandle add(const Item& item, size_t type) {

        if (!type) return INVALID_ENTITY_HANDLE;

        size_t maxElements = (1ULL << indexBits);
        if (mLiveEntries == maxElements) return INVALID_ENTITY_HANDLE;

        size_t newIndex = mFirstFreeIndex;

        EM_DBG("newIndex/firstFree: %zu type: %zu", newIndex, type);

        size_t neededCapacity = newIndex + 1;
        if (maxElements < neededCapacity) return INVALID_ENTITY_HANDLE;

        size_t currentCapacity = mEntries.size();
        size_t nextCapacity = neededCapacity << 1;
        if (nextCapacity > maxElements) nextCapacity = maxElements;

        EM_DBG("needed/current/next capacity: %zu %zu %zu",
               neededCapacity,
               currentCapacity,
               nextCapacity);

        if (neededCapacity > mEntries.size()) {
            mEntries.resize(nextCapacity);
            for (size_t i = currentCapacity; i < nextCapacity; ++i) {
                mEntries[i].handle = makeHandle(i, 0, type);
                mEntries[i].nextFreeIndex = i + 1;
                EM_DBG("new un-init entry: index %zu nextFree %zu",
                       i, i + 1);
            }
        }

        mEntries[newIndex].handle =
            makeHandle(newIndex, mEntries[newIndex].liveGeneration, type);
        mEntries[newIndex].item = item;

        mFirstFreeIndex = mEntries[newIndex].nextFreeIndex;
        EM_DBG("created. new first free: %zu", mFirstFreeIndex);

        ++mLiveEntries;

        EM_DBG("result handle: 0x%llx", (unsigned long long)mEntries[newIndex].handle);

        return mEntries[newIndex].handle;
    }

    EntityHandle addFixed(EntityHandle fixedHandle, const Item& item, size_t type) {
        // 3 cases:
        // 1. handle is not allocated and doesn't correspond to mFirstFreeIndex
        bool isFreeListNonHead = false;
        // 2. handle already exists (replace)
        bool isAlloced = false;
        // 3. index(handle) == mFirstFreeIndex
        bool isFreeListHead = false;

        if (!type) return INVALID_ENTITY_HANDLE;

        size_t maxElements = (1ULL << indexBits);
        if (mLiveEntries == maxElements) return INVALID_ENTITY_HANDLE;

        size_t newIndex = getHandleIndex(fixedHandle);

        EM_DBG("newIndex/firstFree: %zu type: %zu", newIndex, type);

        size_t neededCapacity = newIndex + 1;

        if (maxElements < neededCapacity) return INVALID_ENTITY_HANDLE;

        size_t currentCapacity = mEntries.size();
        size_t nextCapacity = neededCapacity << 1;
        if (nextCapacity > maxElements) nextCapacity = maxElements;

        EM_DBG("needed/current/next capacity: %zu %zu %zu",
               neededCapacity,
               currentCapacity,
               nextCapacity);

        if (neededCapacity > mEntries.size()) {
            mEntries.resize(nextCapacity);
            for (size_t i = currentCapacity; i < nextCapacity; ++i) {
                mEntries[i].handle = makeHandle(i, 0, type);
                mEntries[i].nextFreeIndex = i + 1;
                EM_DBG("new un-init entry: index %zu nextFree %zu",
                       i, i + 1);
            }
        }

        // Now we ensured that there is enough space to talk about the entry of
        // this |fixedHandle|.
        if (mFirstFreeIndex == newIndex) {
            isFreeListHead = true;
        } else {
            auto& entry = mEntries[newIndex];
            if (entry.liveGeneration == getHandleGeneration(entry.handle)) {
                isAlloced = true;
            } else {
                isFreeListNonHead = true;
            }
        }

        mEntries[newIndex].handle = fixedHandle;
        mEntries[newIndex].liveGeneration = getHandleGeneration(fixedHandle);
        mEntries[newIndex].item = item;

        EM_DBG("new index: %zu", newIndex);

        if (isFreeListHead) {

            EM_DBG("first free index reset from %zu to %zu",
                    mFirstFreeIndex, mEntries[newIndex].nextFreeIndex);

            mFirstFreeIndex = mEntries[newIndex].nextFreeIndex;

            ++mLiveEntries;

        } else if (isAlloced) {
            // Already replaced whatever is there, and since it's already allocated,
            // no need to update freelist.
            EM_DBG("entry at %zu already alloced. replacing.", newIndex);
        } else if (isFreeListNonHead) {
            // Go through the freelist and skip over the entry we just added.
            size_t prevEntryIndex = mFirstFreeIndex;

            EM_DBG("in free list but not head. reorganizing freelist. "
                   "start at %zu -> %zu",
                   mFirstFreeIndex, mEntries[prevEntryIndex].nextFreeIndex);

            while (mEntries[prevEntryIndex].nextFreeIndex != newIndex) {
                EM_DBG("next: %zu -> %zu",
                       prevEntryIndex,
                       mEntries[prevEntryIndex].nextFreeIndex);
                prevEntryIndex =
                    mEntries[prevEntryIndex].nextFreeIndex;
            }

            EM_DBG("finished. set prev entry %zu to new entry's next, %zu",
                    prevEntryIndex, mEntries[newIndex].nextFreeIndex);

            mEntries[prevEntryIndex].nextFreeIndex =
                mEntries[newIndex].nextFreeIndex;

            ++mLiveEntries;
        }

        return fixedHandle;
    }
    void remove(EntityHandle h) {

        if (get(h) == nullptr) return;

        size_t index = getHandleIndex(h);

        EM_DBG("remove handle: 0x%llx -> index %zu", (unsigned long long)h, index);

        auto& entry = mEntries[index];

        EM_DBG("handle gen: %zu entry gen: %zu", getHandleGeneration(h), entry.liveGeneration);

        ++entry.liveGeneration;
        if ((entry.liveGeneration == 0) ||
            (entry.liveGeneration == (1ULL << generationBits))) {
            entry.liveGeneration = 1;
        }

        entry.nextFreeIndex = mFirstFreeIndex;

        mFirstFreeIndex = index;

        EM_DBG("new first free: %zu next free: %zu", mFirstFreeIndex, entry.nextFreeIndex);

        --mLiveEntries;
    }

    Item* get(EntityHandle h) {
        EM_DBG("get 0x%llx", (unsigned long long)h);
        size_t index = getHandleIndex(h);
        if (index >= mEntries.size()) {
            return nullptr;
        }

        auto& entry = mEntries[index];
        if (entry.liveGeneration != getHandleGeneration(h)) {
            return nullptr;
        }

        return &entry.item;
    }

    const Item* get_const(EntityHandle h) const {
        size_t index = getHandleIndex(h);
        if (index >= mEntries.size()) return nullptr;

        const auto& entry = mEntries.data() + index;
        if (entry->liveGeneration != getHandleGeneration(h)) return nullptr;

        return &entry->item;
    }

    bool isLive(EntityHandle h) const {
        size_t index = getHandleIndex(h);
        if (index >= mEntries.size()) return false;

        const auto& entry = mEntries[index];

        return (entry.liveGeneration == getHandleGeneration(h));
    }

    void forEachEntry(IteratorFunc func) {
        for (auto& entry: mEntries) {
            auto handle = entry.handle;
            bool live = isLive(handle);
            auto& item = entry.item;
            func(live, handle, item);
        }
    }

    void forEachLiveEntry(IteratorFunc func) {
        for (auto& entry: mEntries) {
            auto handle = entry.handle;
            bool live = isLive(handle);

            if (!live) continue;

            auto& item = entry.item;
            func(live, handle, item);
        }
    }

    void forEachLiveEntry_const(ConstIteratorFunc func) const {
        for (auto& entry: mEntries) {
            auto handle = entry.handle;
            bool live = isLive(handle);

            if (!live) continue;

            const auto& item = entry.item;
            func(live, handle, item);
        }
    }

private:
    void reserve(size_t count) {
        if (mEntries.size() < count) {
            mEntries.resize(count);
        }
        for (size_t i = 0; i < count; ++i) {
            mEntries[i].handle = makeHandle(i, 0, 1);
            mEntries[i].nextFreeIndex = i + 1;
            ++mEntries[i].liveGeneration;
            if ((mEntries[i].liveGeneration == 0) ||
                    (mEntries[i].liveGeneration == (1ULL << generationBits))) {
                mEntries[i].liveGeneration = 1;
            }
            EM_DBG("new un-init entry: index %zu nextFree %zu",
                    i, i + 1);
        }
    }

    std::vector<EntityEntry> mEntries;
    size_t mFirstFreeIndex;
    size_t mLiveEntries;
};

// Tracks components over a given space of entities.
// Looking up by entity index is slower, but takes less space overall versus
// a flat array that parallels the entities.
template<size_t indexBits,
         size_t generationBits,
         size_t typeBits,
         class Data>
class ComponentManager {
public:

    static_assert(64 == (indexBits + generationBits + typeBits),
                  "bits of index, generation, and type must add to 64");

    using ComponentHandle = uint64_t;
    using EntityHandle = uint64_t;
    using ComponentIteratorFunc = std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, Data& data)>;
    using ConstComponentIteratorFunc = std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, const Data& data)>;

    // Adds the given |data| and associates it with EntityHandle.
    // We can also opt-in to immediately tracking the handle in the reverse mapping,
    // which has an upfront cost in runtime.
    // Many uses of ComponentManager don't really need to track the associated entity handle,
    // so it is opt-in.

    ComponentHandle add(
        EntityHandle h,
        const Data& data,
        size_t type,
        bool tracked = false) {

        InternalItem item = { h, data, tracked };
        auto res = static_cast<ComponentHandle>(mData.add(item, type));

        if (tracked) {
            mEntityToComponentMap[h] = res;
        }

        return res;
    }

    void clear() {
        mData.clear();
        mEntityToComponentMap.clear();
    }

    // If we didn't explicitly track, just fail.
    ComponentHandle getComponentHandle(EntityHandle h) const {
        auto componentHandlePtr = android::base::find(mEntityToComponentMap, h);
        if (!componentHandlePtr) return INVALID_COMPONENT_HANDLE;
        return *componentHandlePtr;
    }

    EntityHandle getEntityHandle(ComponentHandle h) const {
        return mData.get(h)->entityHandle;
    }

    void removeByEntity(EntityHandle h) {
        auto componentHandle = getComponentHandle(h);
        removeByComponent(componentHandle);
    }

    void removeByComponent(ComponentHandle h) {
        auto item = mData.get(h);

        if (!item) return;
        if (item->tracked) {
            mEntityToComponentMap.erase(item->entityHandle);
        }

        mData.remove(h);
    }

    Data* getByEntity(EntityHandle h) {
        return getByComponent(getComponentHandle(h));
    }

    Data* getByComponent(ComponentHandle h) {
        auto item = mData.get(h);
        if (!item) return nullptr;
        return &(item->data);
    }

    void forEachComponent(ComponentIteratorFunc func) {
        mData.forEachEntry(
            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, InternalItem& item) {
                func(live, componentHandle, item.entityHandle, item.data);
        });
    }

    void forEachLiveComponent(ComponentIteratorFunc func) {
        mData.forEachLiveEntry(
            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, InternalItem& item) {
                func(live, componentHandle, item.entityHandle, item.data);
        });
    }

    void forEachLiveComponent_const(ConstComponentIteratorFunc func) const {
        mData.forEachLiveEntry_const(
            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, const InternalItem& item) {
                func(live, componentHandle, item.entityHandle, item.data);
        });
    }

private:
    struct InternalItem {
        EntityHandle entityHandle;
        Data data;
        bool tracked;
    };

    using InternalEntityManager = EntityManager<indexBits, generationBits, typeBits, InternalItem>;
    using EntityToComponentMap = std::unordered_map<EntityHandle, ComponentHandle>;

    mutable InternalEntityManager mData;
    EntityToComponentMap mEntityToComponentMap;
};

// ComponentManager, but unpacked; uses the same index space as the associated
// entities. Takes more space by default, but not more if all entities have this component.
template<size_t indexBits,
         size_t generationBits,
         size_t typeBits,
         class Data>
class UnpackedComponentManager {
public:
    using ComponentHandle = uint64_t;
    using EntityHandle = uint64_t;
    using ComponentIteratorFunc =
        std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, Data& data)>;
    using ConstComponentIteratorFunc =
        std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, const Data& data)>;

    EntityHandle add(EntityHandle h, const Data& data) {

        size_t index = indexOfEntity(h);

        if (index + 1 > mItems.size()) {
            mItems.resize((index + 1) * 2);
        }

        mItems[index].live = true;
        mItems[index].handle = h;
        mItems[index].data = data;

        return h;
    }

    void clear() {
        mItems.clear();
    }

    void remove(EntityHandle h) {
        size_t index = indexOfEntity(h);
        if (index >= mItems.size()) return;
        mItems[index].live = false;
    }

    Data* get(EntityHandle h) {
        size_t index = indexOfEntity(h);

        if (index + 1 > mItems.size()) {
            mItems.resize((index + 1) * 2);
        }

        auto item = mItems.data() + index;
        if (!item->live) return nullptr;
        return &item->data;
    }

    const Data* get_const(EntityHandle h) const {
        size_t index = indexOfEntity(h);

        if (index + 1 > mItems.size()) {
            return nullptr;
        }

        auto item = mItems.data() + index;
        if (!item->live) return nullptr;
        return &item->data;
    }

    void forEachComponent(ComponentIteratorFunc func) {
        for (auto& item : mItems) {
            func(item.live, item.handle, item.handle, item.data);
        }
    }

    void forEachLiveComponent(ComponentIteratorFunc func) {
        for (auto& item : mItems) {
            if (item.live) func(item.live, item.handle, item.handle, item.data);
        }
    }

    void forEachLiveComponent_const(ConstComponentIteratorFunc func) const {
        for (auto& item : mItems) {
            if (item.live) func(item.live, item.handle, item.handle, item.data);
        }
    }

private:
    static size_t indexOfEntity(EntityHandle h) {
        return EntityManager<indexBits, generationBits, typeBits, int>::getHandleIndex(h);
    }

    struct InternalItem {
        bool live = false;
        EntityHandle handle = 0;
        Data data;
    };

    std::vector<InternalItem> mItems;
};

} // namespace android
} // namespace base
