#ifndef _RIVE_IMPORT_STACK_HPP_
#define _RIVE_IMPORT_STACK_HPP_
#include "rive/status_code.hpp"
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <algorithm>

namespace rive {
    class ImportStackObject {
    public:
        virtual ~ImportStackObject() {}
        virtual StatusCode resolve() { return StatusCode::Ok; }
        virtual bool readNullObject() { return false; }
    };

    class ImportStack {
    private:
        std::unordered_map<uint16_t, ImportStackObject*> m_Latests;
        std::vector<ImportStackObject*> m_LastAdded;

    public:
        template <typename T = ImportStackObject> T* latest(uint16_t coreType) {
            auto itr = m_Latests.find(coreType);
            if (itr == m_Latests.end()) {
                return nullptr;
            }
            return reinterpret_cast<T*>(itr->second);
        }

        StatusCode makeLatest(uint16_t coreType, ImportStackObject* object) {
            // Clean up the old object in the stack.
            auto itr = m_Latests.find(coreType);
            if (itr != m_Latests.end()) {
                auto stackObject = itr->second;

                // Remove it from latests.
                auto itr = std::find(m_LastAdded.begin(), m_LastAdded.end(), stackObject);
                if (itr != m_LastAdded.end()) {
                    m_LastAdded.erase(itr);
                }

                StatusCode code = stackObject->resolve();
                delete stackObject;
                if (code != StatusCode::Ok) {
                    m_Latests.erase(coreType);
                    return code;
                }
            }

            // Set the new one.
            if (object == nullptr) {
                m_Latests.erase(coreType);
            } else {
                m_Latests[coreType] = object;
                m_LastAdded.push_back(object);
            }
            return StatusCode::Ok;
        }

        StatusCode resolve() {
            for (auto& pair : m_Latests) {
                StatusCode code = pair.second->resolve();
                if (code != StatusCode::Ok) {
                    return code;
                }
            }
            return StatusCode::Ok;
        }

        ~ImportStack() {
            for (auto& pair : m_Latests) {
                delete pair.second;
            }
        }

        bool readNullObject() {
            for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) {
                if ((*itr)->readNullObject()) {
                    return true;
                }
            }
            return false;
        }
    };
} // namespace rive
#endif