// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.meta;

import java.util.Map;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import javax.annotation.Nonnull;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;

public class DynamicMetaStore<K> extends AbstractMetaStore<K>
{
    @Nonnull
    private final Int2ObjectMap<Object> map;
    
    public DynamicMetaStore(final K parent, final IMetaRegistry<K> registry) {
        this(parent, (IMetaRegistry<Object>)registry, false);
    }
    
    public DynamicMetaStore(final K parent, final IMetaRegistry<K> registry, final boolean bypassEncodedCache) {
        super(parent, registry, bypassEncodedCache);
        this.map = new Int2ObjectOpenHashMap<Object>();
    }
    
    @Override
    protected <T> T get0(@Nonnull final MetaKey<T> key) {
        return (T)this.map.get(key.getId());
    }
    
    @Override
    public <T> T getMetaObject(@Nonnull final MetaKey<T> key) {
        T o = (T)this.get0((MetaKey<Object>)key);
        if (o == null) {
            this.map.put(key.getId(), o = this.decodeOrNewMetaObject(key));
        }
        return o;
    }
    
    @Override
    public <T> T getIfPresentMetaObject(@Nonnull final MetaKey<T> key) {
        return (T)this.get0((MetaKey<Object>)key);
    }
    
    @Override
    public <T> T putMetaObject(@Nonnull final MetaKey<T> key, final T obj) {
        this.markMetaStoreDirty();
        return (T)this.map.put(key.getId(), obj);
    }
    
    @Override
    public <T> T removeMetaObject(@Nonnull final MetaKey<T> key) {
        this.markMetaStoreDirty();
        return (T)this.map.remove(key.getId());
    }
    
    @Nullable
    @Override
    public <T> T removeSerializedMetaObject(final MetaKey<T> key) {
        this.markMetaStoreDirty();
        if (key instanceof final PersistentMetaKey persistentMetaKey) {
            this.tryDecodeUnknownKey((PersistentMetaKey<Object>)persistentMetaKey);
        }
        return (T)this.removeMetaObject((MetaKey<Object>)key);
    }
    
    @Override
    public boolean hasMetaObject(@Nonnull final MetaKey<?> key) {
        return this.map.containsKey(key.getId());
    }
    
    @Override
    public void forEachMetaObject(@Nonnull final IMetaStore.MetaEntryConsumer consumer) {
        for (final Int2ObjectMap.Entry entry : this.map.int2ObjectEntrySet()) {
            consumer.accept(entry.getIntKey(), entry.getValue());
        }
    }
    
    @Nonnull
    public DynamicMetaStore<K> clone(final K parent) {
        final DynamicMetaStore<K> clone = new DynamicMetaStore<K>(parent, this.registry);
        clone.map.putAll((Map<?, ?>)this.map);
        return clone;
    }
    
    public void copyFrom(@Nonnull final DynamicMetaStore<K> other) {
        this.markMetaStoreDirty();
        if (this.registry != other.registry) {
            throw new IllegalArgumentException("Wrong registry used in `copyFrom`.");
        }
        this.map.putAll((Map<?, ?>)other.map);
    }
}
