#ifndef PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP
#define PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP


#include <utility>
#include <map>
#include "EvalValue.hpp"
#include "../EvalValuePointer.hpp"

using namespace std;

namespace Porygon::Evaluation {
    class NumericalTableEvalValue : public EvalValue {
        const shared_ptr<vector<EvalValuePointer>> _table;
        const size_t _hash;

        explicit NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>>  table, size_t hash)
                :  _table(std::move(table)),
                   _hash(hash)
        {
        }

    public:
        explicit NumericalTableEvalValue(shared_ptr<vector<EvalValuePointer>> table);

        [[nodiscard]]
        inline TypeClass GetTypeClass() const final {
            return TypeClass::Table;
        }

        [[nodiscard]]
        inline size_t GetHashCode() const final {
            return _hash;
        }

        [[nodiscard]]
        inline bool operator==(const EvalValue *b) const final {
            return this->_hash == b->GetHashCode();
        }

        [[nodiscard]]
        inline EvalValue* Clone() const final {
            return new NumericalTableEvalValue(_table, _hash);
        }

        [[nodiscard]]
        inline const EvalValue* IndexValue(const EvalValue *val) const final {
            const auto index = val->EvaluateInteger() - 1;
            return this->_table->at(index).Clone();
        }

        [[nodiscard]]
        inline EvalValue* IndexValue(uint32_t hash) const final {
            return this->_table->at(hash - 1)-> Clone();
        }

        inline void SetIndexValue(const EvalValue *key, const EvalValue* value) const final {
            auto index = key->EvaluateInteger();
            this->_table->at(index - 1) = value;
        }

        [[nodiscard]]
        Iterator * GetKeyIterator() const final;

        [[nodiscard]]
        inline shared_ptr<vector<EvalValuePointer>> GetTable() const{
            return _table;
        };
    };
}

#undef iteratorKind

#endif //PORYGONLANG_NUMERICALTABLEEVALVALUE_HPP
