
#ifndef PORYGONLANG_TABLESCRIPTTYPE_HPP
#define PORYGONLANG_TABLESCRIPTTYPE_HPP
#include <unordered_map>
#include "../Binder/BoundVariables/BoundVariable.hpp"

namespace Porygon{
    class TableScriptType : public ScriptType{
        const map<Utilities::HashedString, BoundVariable*>* _values;
        const int _localVariableCount;
    public:
        explicit TableScriptType(map<Utilities::HashedString, BoundVariable*>* values, int localVariableCount)
                : ScriptType(TypeClass::Table),
                  _values(values),
                  _localVariableCount(localVariableCount)
        {}

        ~TableScriptType() final{
            for (auto i : *_values){
                delete i.second;
            }
            delete _values;
        }

        [[nodiscard]]
        inline bool CanBeIndexedWith(const ScriptType* indexer) const final{
            return indexer->GetClass() == TypeClass ::String;
        }

        [[nodiscard]] bool CanBeIndexedWithIdentifier(uint32_t hash) const final{
            return true;
        }

        shared_ptr<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
            auto stringKey = dynamic_cast<const StringScriptType*>(indexer);
            if (stringKey->IsKnownAtBind()){
                return _values-> at(Utilities::HashedString::CreateLookup(stringKey->GetHashValue()))->GetType();
            }
            throw "TODO: indexing with dynamic keys";
        }

        [[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final{
            return _values-> at(Utilities::HashedString::CreateLookup(hash))->GetType();
        }

        [[nodiscard]] inline const map<Utilities::HashedString, BoundVariable*>* GetValues() const{
            return _values;
        }
    };
}

#include "ScriptType.hpp"

#endif //PORYGONLANG_TABLESCRIPTTYPE_HPP
