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

package com.hypixel.hytale.server.npc.commands;

import it.unimi.dsi.fastutil.ints.IntArrayList;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.npc.asset.builder.BuilderInfo;
import it.unimi.dsi.fastutil.Pair;
import java.util.List;
import java.util.logging.Level;
import com.hypixel.hytale.server.npc.systems.PositionCacheSystems;
import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.server.npc.util.expression.ExecutionContext;
import com.hypixel.hytale.server.npc.role.support.RoleStats;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.function.consumer.TriConsumer;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Store;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;

public class NPCSensorStatsCommand extends AbstractPlayerCommand
{
    public NPCSensorStatsCommand() {
        super("sensorstats", "server.commands.npc.sensorstats.desc");
    }
    
    @Override
    protected void execute(@Nonnull final CommandContext context, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref, @Nonnull final PlayerRef playerRef, @Nonnull final World world) {
        final NPCPlugin npcPlugin = NPCPlugin.get();
        final List<String> roles = npcPlugin.getRoleTemplateNames(true);
        if (roles.isEmpty()) {
            context.sendMessage(Message.translation("server.commands.npc.sensorstats.noroles"));
            return;
        }
        roles.sort(String::compareToIgnoreCase);
        final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
        assert transformComponent != null;
        final Vector3d pos = new Vector3d(transformComponent.getPosition());
        final String name = roles.getFirst();
        final int roleIndex = NPCPlugin.get().getIndex(name);
        if (roleIndex < 0) {
            throw new IllegalStateException("No such valid role: " + name);
        }
        final Pair<Ref<EntityStore>, NPCEntity> npcPair = npcPlugin.spawnEntity(store, roleIndex, pos, null, null, null);
        final NPCEntity npcComponent = npcPair.second();
        final StringBuilder out = new StringBuilder();
        final RoleStats roleStats = new RoleStats();
        for (int i = 0; i < roles.size(); ++i) {
            final String roleName = roles.get(i);
            try {
                roleStats.clear();
                final BuilderInfo builderInfo = NPCPlugin.get().prepareRoleBuilderInfo(NPCPlugin.get().getIndex(roleName));
                final Builder<Role> roleBuilder = (Builder<Role>)builderInfo.getBuilder();
                final BuilderSupport builderSupport = new BuilderSupport(NPCPlugin.get().getBuilderManager(), npcComponent, EntityStore.REGISTRY.newHolder(), new ExecutionContext(), roleBuilder, roleStats);
                final Role role = NPCPlugin.buildRole(roleBuilder, builderInfo, builderSupport, roleIndex);
                PositionCacheSystems.initialisePositionCache(role, builderSupport.getStateEvaluator(), 0.0);
            }
            catch (final Throwable t) {
                context.sendMessage(Message.translation("server.commands.npc.spawn.templateNotFound").param("template", roleName));
                npcPlugin.getLogger().at(Level.WARNING).log("Error spawning role " + roleName + ": " + t.getMessage());
                continue;
            }
            if (!isRangesEmpty(roleStats, true)) {
                out.append('\n').append("PLY ");
                formatRanges(out, roleStats, "S=", true, RoleStats.RangeType.SORTED, 25);
                formatRanges(out, roleStats, "U=", true, RoleStats.RangeType.UNSORTED, 9);
                formatRanges(out, roleStats, "A=", true, RoleStats.RangeType.AVOIDANCE, 9);
                formatBuckets(out, roleStats, "B=", true, 20);
                out.append(roleName);
            }
            if (!isRangesEmpty(roleStats, false)) {
                out.append('\n').append("ENT ");
                formatRanges(out, roleStats, "S=", false, RoleStats.RangeType.SORTED, 25);
                formatRanges(out, roleStats, "U=", false, RoleStats.RangeType.UNSORTED, 9);
                formatRanges(out, roleStats, "A=", false, RoleStats.RangeType.AVOIDANCE, 9);
                formatBuckets(out, roleStats, "B=", false, 20);
                out.append(roleName);
            }
        }
        npcPlugin.getLogger().at(Level.INFO).log(out.toString());
        npcComponent.remove();
    }
    
    private static boolean isRangesEmpty(@Nonnull final RoleStats roleStats, final boolean isPlayer) {
        return roleStats.getRanges(isPlayer, RoleStats.RangeType.SORTED) == null && roleStats.getRanges(isPlayer, RoleStats.RangeType.UNSORTED) == null && roleStats.getRanges(isPlayer, RoleStats.RangeType.AVOIDANCE) == null;
    }
    
    private static void formatBuckets(@Nonnull final StringBuilder builder, @Nonnull final RoleStats roleStats, @Nonnull final String label, final boolean isPlayer, final int width) {
        builder.append(label);
        int length = builder.length();
        final IntArrayList buckets = roleStats.getBuckets(isPlayer);
        for (int i = 0; i < buckets.size(); ++i) {
            builder.append(buckets.getInt(i)).append(" ");
        }
        length = width + length - builder.length();
        if (length > 0) {
            builder.append(" ".repeat(length));
        }
    }
    
    private static void formatRanges(@Nonnull final StringBuilder builder, @Nonnull final RoleStats roleStats, @Nonnull final String label, final boolean isPlayer, @Nonnull final RoleStats.RangeType rangeType, final int width) {
        builder.append(label);
        int length = builder.length();
        final int[] ranges = roleStats.getRangesSorted(isPlayer, rangeType);
        if (ranges != null && ranges.length != 0) {
            for (final int range : ranges) {
                builder.append(range).append(" ");
            }
        }
        else {
            builder.append("- ");
        }
        length = width + length - builder.length();
        if (length > 0) {
            builder.append(" ".repeat(length));
        }
    }
}
