package net.minecraft.server.commands;

import com.mojang.brigadier.Message;
import net.minecraft.commands.SharedSuggestionProvider;
import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.network.chat.ComponentUtils;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.world.level.storage.LevelData;
import java.util.List;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.level.dimension.DimensionType;
import java.util.Collection;
import com.google.common.collect.Lists;
import net.minecraft.server.packs.repository.UnopenedPack;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import net.minecraft.commands.Commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.commands.CommandSourceStack;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;

public class DataPackCommand {
    private static final DynamicCommandExceptionType ERROR_UNKNOWN_PACK;
    private static final DynamicCommandExceptionType ERROR_PACK_ALREADY_ENABLED;
    private static final DynamicCommandExceptionType ERROR_PACK_ALREADY_DISABLED;
    private static final SuggestionProvider<CommandSourceStack> SELECTED_PACKS;
    private static final SuggestionProvider<CommandSourceStack> AVAILABLE_PACKS;
    
    public static void register(final CommandDispatcher<CommandSourceStack> commandDispatcher) {
        commandDispatcher.register((LiteralArgumentBuilder)((LiteralArgumentBuilder)((LiteralArgumentBuilder)((LiteralArgumentBuilder)Commands.literal("datapack").requires(cq -> cq.hasPermission(2))).then(Commands.literal("enable").then(((RequiredArgumentBuilder)((RequiredArgumentBuilder)((RequiredArgumentBuilder)((RequiredArgumentBuilder)Commands.argument("name", (com.mojang.brigadier.arguments.ArgumentType<Object>)StringArgumentType.string()).suggests((SuggestionProvider)DataPackCommand.AVAILABLE_PACKS).executes(commandContext -> enablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", true), (list, yt) -> yt.getDefaultPosition().<UnopenedPack, UnopenedPack>insert(list, yt, yt -> yt, false)))).then(Commands.literal("after").then(Commands.argument("existing", (com.mojang.brigadier.arguments.ArgumentType<Object>)StringArgumentType.string()).suggests((SuggestionProvider)DataPackCommand.SELECTED_PACKS).executes(commandContext -> enablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", true), (list, yt) -> list.add(list.indexOf(getPack((CommandContext<CommandSourceStack>)commandContext, "existing", false)) + 1, yt)))))).then(Commands.literal("before").then(Commands.argument("existing", (com.mojang.brigadier.arguments.ArgumentType<Object>)StringArgumentType.string()).suggests((SuggestionProvider)DataPackCommand.SELECTED_PACKS).executes(commandContext -> enablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", true), (list, yt) -> list.add(list.indexOf(getPack((CommandContext<CommandSourceStack>)commandContext, "existing", false)), yt)))))).then(Commands.literal("last").executes(commandContext -> enablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", true), List::add)))).then(Commands.literal("first").executes(commandContext -> enablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", true), (list, yt) -> list.add(0, yt))))))).then(Commands.literal("disable").then(Commands.argument("name", (com.mojang.brigadier.arguments.ArgumentType<Object>)StringArgumentType.string()).suggests((SuggestionProvider)DataPackCommand.SELECTED_PACKS).executes(commandContext -> disablePack((CommandSourceStack)commandContext.getSource(), getPack((CommandContext<CommandSourceStack>)commandContext, "name", false)))))).then(((LiteralArgumentBuilder)((LiteralArgumentBuilder)Commands.literal("list").executes(commandContext -> listPacks((CommandSourceStack)commandContext.getSource()))).then(Commands.literal("available").executes(commandContext -> listAvailablePacks((CommandSourceStack)commandContext.getSource())))).then(Commands.literal("enabled").executes(commandContext -> listEnabledPacks((CommandSourceStack)commandContext.getSource())))));
    }
    
    private static int enablePack(final CommandSourceStack cq, final UnopenedPack yt, final Inserter a) throws CommandSyntaxException {
        final PackRepository<UnopenedPack> yq4 = cq.getServer().getPackRepository();
        final List<UnopenedPack> list5 = Lists.newArrayList(yq4.getSelected());
        a.apply(list5, yt);
        yq4.setSelected(list5);
        final LevelData crm6 = cq.getServer().getLevel(DimensionType.OVERWORLD).getLevelData();
        crm6.getEnabledDataPacks().clear();
        yq4.getSelected().forEach(yt -> crm6.getEnabledDataPacks().add(yt.getId()));
        crm6.getDisabledDataPacks().remove(yt.getId());
        cq.sendSuccess(new TranslatableComponent("commands.datapack.enable.success", new Object[] { yt.getChatLink(true) }), true);
        cq.getServer().reloadResources();
        return yq4.getSelected().size();
    }
    
    private static int disablePack(final CommandSourceStack cq, final UnopenedPack yt) {
        final PackRepository<UnopenedPack> yq3 = cq.getServer().getPackRepository();
        final List<UnopenedPack> list4 = Lists.newArrayList(yq3.getSelected());
        list4.remove(yt);
        yq3.setSelected(list4);
        final LevelData crm5 = cq.getServer().getLevel(DimensionType.OVERWORLD).getLevelData();
        crm5.getEnabledDataPacks().clear();
        yq3.getSelected().forEach(yt -> crm5.getEnabledDataPacks().add(yt.getId()));
        crm5.getDisabledDataPacks().add(yt.getId());
        cq.sendSuccess(new TranslatableComponent("commands.datapack.disable.success", new Object[] { yt.getChatLink(true) }), true);
        cq.getServer().reloadResources();
        return yq3.getSelected().size();
    }
    
    private static int listPacks(final CommandSourceStack cq) {
        return listEnabledPacks(cq) + listAvailablePacks(cq);
    }
    
    private static int listAvailablePacks(final CommandSourceStack cq) {
        final PackRepository<UnopenedPack> yq2 = cq.getServer().getPackRepository();
        if (yq2.getUnselected().isEmpty()) {
            cq.sendSuccess(new TranslatableComponent("commands.datapack.list.available.none", new Object[0]), false);
        }
        else {
            cq.sendSuccess(new TranslatableComponent("commands.datapack.list.available.success", new Object[] { yq2.getUnselected().size(), ComponentUtils.<UnopenedPack>formatList(yq2.getUnselected(), yt -> yt.getChatLink(false)) }), false);
        }
        return yq2.getUnselected().size();
    }
    
    private static int listEnabledPacks(final CommandSourceStack cq) {
        final PackRepository<UnopenedPack> yq2 = cq.getServer().getPackRepository();
        if (yq2.getSelected().isEmpty()) {
            cq.sendSuccess(new TranslatableComponent("commands.datapack.list.enabled.none", new Object[0]), false);
        }
        else {
            cq.sendSuccess(new TranslatableComponent("commands.datapack.list.enabled.success", new Object[] { yq2.getSelected().size(), ComponentUtils.<UnopenedPack>formatList(yq2.getSelected(), yt -> yt.getChatLink(true)) }), false);
        }
        return yq2.getSelected().size();
    }
    
    private static UnopenedPack getPack(final CommandContext<CommandSourceStack> commandContext, final String string, final boolean boolean3) throws CommandSyntaxException {
        final String string2 = StringArgumentType.getString((CommandContext)commandContext, string);
        final PackRepository<UnopenedPack> yq5 = ((CommandSourceStack)commandContext.getSource()).getServer().getPackRepository();
        final UnopenedPack yt6 = yq5.getPack(string2);
        if (yt6 == null) {
            throw DataPackCommand.ERROR_UNKNOWN_PACK.create(string2);
        }
        final boolean boolean4 = yq5.getSelected().contains(yt6);
        if (boolean3 && boolean4) {
            throw DataPackCommand.ERROR_PACK_ALREADY_ENABLED.create(string2);
        }
        if (!boolean3 && !boolean4) {
            throw DataPackCommand.ERROR_PACK_ALREADY_DISABLED.create(string2);
        }
        return yt6;
    }
    
    static {
        final TranslatableComponent translatableComponent;
        ERROR_UNKNOWN_PACK = new DynamicCommandExceptionType(object -> {
            new TranslatableComponent("commands.datapack.unknown", new Object[] { object });
            return translatableComponent;
        });
        final TranslatableComponent translatableComponent2;
        ERROR_PACK_ALREADY_ENABLED = new DynamicCommandExceptionType(object -> {
            new TranslatableComponent("commands.datapack.enable.failed", new Object[] { object });
            return translatableComponent2;
        });
        final TranslatableComponent translatableComponent3;
        ERROR_PACK_ALREADY_DISABLED = new DynamicCommandExceptionType(object -> {
            new TranslatableComponent("commands.datapack.disable.failed", new Object[] { object });
            return translatableComponent3;
        });
        SELECTED_PACKS = ((commandContext, suggestionsBuilder) -> SharedSuggestionProvider.suggest(((CommandSourceStack)commandContext.getSource()).getServer().getPackRepository().getSelected().stream().map(UnopenedPack::getId).<String>map(StringArgumentType::escapeIfRequired), suggestionsBuilder));
        AVAILABLE_PACKS = ((commandContext, suggestionsBuilder) -> SharedSuggestionProvider.suggest(((CommandSourceStack)commandContext.getSource()).getServer().getPackRepository().getUnselected().stream().map(UnopenedPack::getId).<String>map(StringArgumentType::escapeIfRequired), suggestionsBuilder));
    }
    
    interface Inserter {
        void apply(final List<UnopenedPack> list, final UnopenedPack yt) throws CommandSyntaxException;
    }
}
