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

package com.hypixel.hytale.builtin.tagset;

import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.Objects;
import com.hypixel.hytale.assetstore.AssetRegistry;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import java.util.function.Function;
import com.hypixel.hytale.assetstore.codec.AssetCodec;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
import com.hypixel.hytale.assetstore.AssetStore;
import com.hypixel.hytale.server.core.asset.HytaleAssetStore;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import java.util.Map;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;

public class TagSetPlugin extends JavaPlugin
{
    private static TagSetPlugin instance;
    private final Map<Class<? extends TagSet>, TagSetLookup> lookups;
    
    public static TagSetPlugin get() {
        return TagSetPlugin.instance;
    }
    
    public TagSetPlugin(@Nonnull final JavaPluginInit init) {
        super(init);
        this.lookups = new ConcurrentHashMap<Class<? extends TagSet>, TagSetLookup>();
    }
    
    @Override
    protected void setup() {
        TagSetPlugin.instance = this;
        AssetRegistry.register(((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(NPCGroup.class, new IndexedLookupTableAssetMap(NPCGroup[]::new)).setPath()).setCodec(NPCGroup.CODEC)).setKeyFunction(NPCGroup::getId)).setReplaceOnRemove(NPCGroup::new).loadsBefore(Interaction.class)).build());
        this.registerTagSetType(NPCGroup.class);
    }
    
    public <T extends TagSet> void registerTagSetType(final Class<T> clazz) {
        if (this.isDisabled()) {
            return;
        }
        this.lookups.computeIfAbsent(clazz, c -> new TagSetLookup());
    }
    
    @Nonnull
    public static <T extends TagSet> TagSetLookup get(final Class<T> clazz) {
        return Objects.requireNonNull(TagSetPlugin.instance.lookups.get(clazz), "Class is not registered with the TagSet module!");
    }
    
    public static class TagSetLookup
    {
        @Nonnull
        private Int2ObjectMap<IntSet> flattenedSets;
        
        public TagSetLookup() {
            this.flattenedSets = Int2ObjectMaps.unmodifiable((Int2ObjectMap<? extends IntSet>)new Int2ObjectOpenHashMap<IntSet>());
        }
        
        public <T extends TagSet> void putAssetSets(@Nonnull final Map<String, T> tagSetAssets, @Nonnull final Object2IntMap<String> tagSetIndexMap, @Nonnull final Object2IntMap<String> tagIndexMap) {
            final TagSetLookupTable<T> lookupTable = new TagSetLookupTable<T>(tagSetAssets, tagSetIndexMap, tagIndexMap);
            this.flattenedSets = Int2ObjectMaps.unmodifiable((Int2ObjectMap<? extends IntSet>)lookupTable.getFlattenedSet());
        }
        
        public boolean tagInSet(final int tagSet, final int tagIndex) {
            final IntSet set = this.flattenedSets.get(tagSet);
            if (set == null) {
                throw new IllegalArgumentException("Attempting to access a tagset which does not exist!");
            }
            return set.contains(tagIndex);
        }
        
        @Nullable
        public IntSet getSet(final int tagSet) {
            return this.flattenedSets.get(tagSet);
        }
    }
}
