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

package com.hypixel.hytale.server.npc.blackboard.view.attitude;

import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.logging.Level;
import com.hypixel.hytale.server.npc.NPCPlugin;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import com.hypixel.hytale.builtin.tagset.TagSetPlugin;
import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
import java.util.Map;
import com.hypixel.hytale.server.npc.config.AttitudeGroup;
import com.hypixel.hytale.server.npc.asset.builder.BuilderManager;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.core.asset.type.attitude.Attitude;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import com.hypixel.hytale.server.core.entity.entities.Player;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;

public class AttitudeMap
{
    @Nullable
    private static final ComponentType<EntityStore, NPCEntity> NPC_COMPONENT_TYPE;
    private static final ComponentType<EntityStore, Player> PLAYER_COMPONENT_TYPE;
    private final Int2ObjectMap<Attitude>[] map;
    
    private AttitudeMap(final Int2ObjectMap<Attitude>[] map) {
        this.map = map;
    }
    
    @Nullable
    public Attitude getAttitude(@Nonnull final Role role, @Nonnull final Ref<EntityStore> target, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final int group = role.getWorldSupport().getAttitudeGroup();
        if (group == Integer.MIN_VALUE) {
            return null;
        }
        final Int2ObjectMap<Attitude> attitudeMap = this.map[group];
        if (attitudeMap == null) {
            return null;
        }
        final NPCEntity npc = componentAccessor.getComponent(target, AttitudeMap.NPC_COMPONENT_TYPE);
        int targetId;
        if (npc != null) {
            targetId = npc.getRoleIndex();
        }
        else {
            if (!componentAccessor.getArchetype(target).contains(AttitudeMap.PLAYER_COMPONENT_TYPE)) {
                return null;
            }
            targetId = BuilderManager.getPlayerGroupID();
        }
        if (targetId == role.getRoleIndex()) {
            return attitudeMap.get(BuilderManager.getSelfGroupID());
        }
        return attitudeMap.get(targetId);
    }
    
    public int getAttitudeGroupCount() {
        return this.map.length;
    }
    
    public void updateAttitudeGroup(final int id, @Nonnull final AttitudeGroup group) {
        final Int2ObjectMap<Attitude> groupMap = Builder.createGroupMap(group);
        this.map[id] = groupMap;
    }
    
    static {
        NPC_COMPONENT_TYPE = NPCEntity.getComponentType();
        PLAYER_COMPONENT_TYPE = Player.getComponentType();
    }
    
    public static class Builder
    {
        private final Int2ObjectMap<Attitude>[] map;
        
        public Builder() {
            this.map = new Int2ObjectMap[AttitudeGroup.getAssetMap().getNextIndex()];
        }
        
        public void addAttitudeGroups(@Nonnull final Map<String, AttitudeGroup> groups) {
            groups.forEach((id, group) -> this.addAttitudeGroup(group));
        }
        
        private void addAttitudeGroup(@Nonnull final AttitudeGroup group) {
            final String key = group.getId();
            final int index = AttitudeGroup.getAssetMap().getIndex(key);
            if (index == Integer.MIN_VALUE) {
                throw new IllegalArgumentException("Unknown key! " + key);
            }
            this.map[index] = createGroupMap(group);
        }
        
        @Nonnull
        private static Int2ObjectMap<Attitude> createGroupMap(@Nonnull final AttitudeGroup group) {
            final TagSetPlugin.TagSetLookup npcGroups = TagSetPlugin.get(NPCGroup.class);
            final Int2ObjectOpenHashMap<Attitude> groupMap = new Int2ObjectOpenHashMap<Attitude>();
            for (final Attitude attitude : Attitude.VALUES) {
                putGroups(group.getId(), npcGroups, group.getAttitudeGroups().get(attitude), attitude, groupMap);
            }
            groupMap.trim();
            return groupMap;
        }
        
        private static void putGroups(final String attitudeGroup, @Nonnull final TagSetPlugin.TagSetLookup npcGroupLookup, @Nullable final String[] group, final Attitude targetAttitude, @Nonnull final Int2ObjectMap<Attitude> targetMap) {
            if (group == null) {
                return;
            }
            for (int length = group.length, i = 0; i < length; ++i) {
                final String item = group[i];
                final int index = NPCGroup.getAssetMap().getIndex(item);
                if (index == Integer.MIN_VALUE) {
                    NPCPlugin.get().getLogger().at(Level.SEVERE).log("Creating attitude groups: NPC Group '%s' does not exist in attitude group '%s'!", item, attitudeGroup);
                }
                else {
                    final IntSet set = npcGroupLookup.getSet(index);
                    if (set != null) {
                        set.forEach(i -> targetMap.put(i, targetAttitude));
                    }
                }
            }
        }
        
        @Nonnull
        public AttitudeMap build() {
            return new AttitudeMap(this.map);
        }
    }
}
