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

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

import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
import java.util.Iterator;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.entity.nameplate.Nameplate;
import com.hypixel.hytale.component.Store;
import java.util.function.BiFunction;
import com.hypixel.hytale.server.npc.role.RoleDebugFlags;
import java.util.EnumSet;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractCommandCollection;

public class NPCDebugCommand extends AbstractCommandCollection
{
    public NPCDebugCommand() {
        super("debug", "server.commands.npc.debug.desc");
        this.addSubCommand(new ShowCommand());
        this.addSubCommand(new SetCommand());
        this.addSubCommand(new ToggleCommand());
        this.addSubCommand(new DefaultsCommand());
        this.addSubCommand(new ClearCommand());
        this.addSubCommand(new PresetsCommand());
    }
    
    private static void modifyFlags(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final Ref<EntityStore> ref, @Nonnull final EnumSet<RoleDebugFlags> flags, @Nonnull final BiFunction<EnumSet<RoleDebugFlags>, EnumSet<RoleDebugFlags>, EnumSet<RoleDebugFlags>> flagsModifier, @Nonnull final Store<EntityStore> store) {
        final EnumSet<RoleDebugFlags> newFlags = flagsModifier.apply(npc.getRoleDebugFlags(), flags);
        if (newFlags == null) {
            return;
        }
        safeSetRoleDebugFlags(npc, ref, newFlags, store);
        printNewFlags(npc, context, newFlags);
    }
    
    private static void safeSetRoleDebugFlags(@Nonnull final NPCEntity npc, @Nonnull final Ref<EntityStore> ref, @Nonnull final EnumSet<RoleDebugFlags> flags, @Nonnull final Store<EntityStore> store) {
        store.tryRemoveComponent(ref, Nameplate.getComponentType());
        npc.setRoleDebugFlags(flags);
    }
    
    private static void printNewFlags(@Nonnull final NPCEntity npc, @Nonnull final CommandContext context, @Nonnull final EnumSet<RoleDebugFlags> newFlags) {
        final String flags = getListOfFlags(newFlags).toString();
        context.sendMessage(Message.translation("server.commands.npc.debug.debugFlagsSet").param("role", npc.getRoleName()).param("flags", flags.isEmpty() ? "<None>" : flags));
    }
    
    @Nonnull
    private static StringBuilder getListOfFlags(@Nonnull final EnumSet<RoleDebugFlags> flags) {
        return RoleDebugFlags.getListOfFlags(flags, new StringBuilder());
    }
    
    public static class ShowCommand extends NPCMultiSelectCommandBase
    {
        public ShowCommand() {
            super("show", "server.commands.npc.debug.show.desc");
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
            final String flags = NPCDebugCommand.getListOfFlags(npc.getRoleDebugFlags()).toString();
            context.sendMessage(Message.translation("server.commands.npc.debug.currentFlags").param("role", npc.getRoleName()).param("flags", flags.isEmpty() ? "<None>" : flags));
        }
    }
    
    public static class SetCommand extends NPCMultiSelectCommandBase
    {
        @Nonnull
        private final RequiredArg<String> flagsArg;
        
        public SetCommand() {
            super("set", "server.commands.npc.debug.set.desc");
            this.flagsArg = this.withRequiredArg("flags", "server.commands.npc.debug.flags.desc", ArgTypes.STRING);
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
            final String flagsString = this.flagsArg.get(context);
            final EnumSet<RoleDebugFlags> flags = RoleDebugFlags.getFlags(flagsString.split(","));
            NPCDebugCommand.modifyFlags(context, npc, ref, flags, (oldFlags, argFlags) -> argFlags, store);
        }
    }
    
    public static class ToggleCommand extends NPCMultiSelectCommandBase
    {
        @Nonnull
        private final RequiredArg<String> flagsArg;
        
        public ToggleCommand() {
            super("toggle", "server.commands.npc.debug.toggle.desc");
            this.flagsArg = this.withRequiredArg("flags", "server.commands.npc.debug.flags.desc", ArgTypes.STRING);
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
            final String flagsString = this.flagsArg.get(context);
            final EnumSet<RoleDebugFlags> flags = RoleDebugFlags.getFlags(flagsString.split(","));
            NPCDebugCommand.modifyFlags(context, npc, ref, flags, (oldFlags, argFlags) -> {
                if (argFlags.isEmpty()) {
                    return null;
                }
                else {
                    final EnumSet<RoleDebugFlags> newFlags = oldFlags.clone();
                    for (final RoleDebugFlags flag : argFlags) {
                        if (newFlags.contains(flag)) {
                            newFlags.remove(flag);
                        }
                        else {
                            newFlags.add(flag);
                        }
                    }
                    return newFlags;
                }
            }, store);
        }
    }
    
    public static class DefaultsCommand extends NPCMultiSelectCommandBase
    {
        public DefaultsCommand() {
            super("defaults", "server.commands.npc.debug.defaults.desc");
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
            NPCDebugCommand.safeSetRoleDebugFlags(npc, ref, RoleDebugFlags.getPreset("default"), store);
        }
    }
    
    public static class ClearCommand extends NPCMultiSelectCommandBase
    {
        public ClearCommand() {
            super("clear", "server.commands.npc.debug.clear.desc");
        }
        
        @Override
        protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
            NPCDebugCommand.safeSetRoleDebugFlags(npc, ref, EnumSet.noneOf(RoleDebugFlags.class), store);
        }
    }
    
    public static class PresetsCommand extends AbstractCommand
    {
        @Nonnull
        private final OptionalArg<String> presetArg;
        
        public PresetsCommand() {
            super("presets", "server.commands.npc.debug.presets.desc");
            this.presetArg = this.withOptionalArg("preset", "server.commands.npc.debug.presets.preset.desc", ArgTypes.STRING);
        }
        
        @Nullable
        @Override
        protected CompletableFuture<Void> execute(@Nonnull final CommandContext context) {
            if (!this.presetArg.provided(context)) {
                final String flags = RoleDebugFlags.getListOfAllFlags(new StringBuilder()).toString();
                final String presets = RoleDebugFlags.getListOfAllPresets(new StringBuilder()).toString();
                final Message message = Message.translation("server.commands.npc.debug.presets.info").param("flags", flags).param("presets", presets);
                context.sendMessage(message);
                return null;
            }
            final String presetName = this.presetArg.get(context);
            if (presetName.isEmpty() || !RoleDebugFlags.havePreset(presetName)) {
                context.sendMessage(Message.translation("server.commands.errors.npc.unknown_debug_preset").param("preset", presetName));
                return null;
            }
            final EnumSet<RoleDebugFlags> flags2 = RoleDebugFlags.getPreset(presetName);
            final String flagString = NPCDebugCommand.getListOfFlags(flags2).toString();
            context.sendMessage(Message.translation("server.commands.npc.debug.preset.info").param("preset", presetName).param("flags", flagString.isEmpty() ? "<None>" : flagString));
            return null;
        }
    }
}
