package net.minecraft.server.commands;

import com.mojang.brigadier.Message;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.phys.Vec3;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.commands.arguments.CompoundTagArgument;
import net.minecraft.commands.arguments.coordinates.Vec3Argument;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import net.minecraft.commands.synchronization.SuggestionProviders;
import com.mojang.brigadier.arguments.ArgumentType;
import net.minecraft.commands.arguments.EntitySummonArgument;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import net.minecraft.commands.Commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;

public class SummonCommand {
    private static final SimpleCommandExceptionType ERROR_FAILED;
    private static final SimpleCommandExceptionType INVALID_POSITION;
    
    public static void register(final CommandDispatcher<CommandSourceStack> commandDispatcher) {
        commandDispatcher.register((LiteralArgumentBuilder)((LiteralArgumentBuilder)Commands.literal("summon").requires(cz -> cz.hasPermission(2))).then(((RequiredArgumentBuilder)Commands.argument("entity", (com.mojang.brigadier.arguments.ArgumentType<Object>)EntitySummonArgument.id()).suggests((SuggestionProvider)SuggestionProviders.SUMMONABLE_ENTITIES).executes(commandContext -> spawnEntity((CommandSourceStack)commandContext.getSource(), EntitySummonArgument.getSummonableEntity((CommandContext<CommandSourceStack>)commandContext, "entity"), ((CommandSourceStack)commandContext.getSource()).getPosition(), new CompoundTag(), true))).then(((RequiredArgumentBuilder)Commands.argument("pos", (com.mojang.brigadier.arguments.ArgumentType<Object>)Vec3Argument.vec3()).executes(commandContext -> spawnEntity((CommandSourceStack)commandContext.getSource(), EntitySummonArgument.getSummonableEntity((CommandContext<CommandSourceStack>)commandContext, "entity"), Vec3Argument.getVec3((CommandContext<CommandSourceStack>)commandContext, "pos"), new CompoundTag(), true))).then(Commands.argument("nbt", (com.mojang.brigadier.arguments.ArgumentType<Object>)CompoundTagArgument.compoundTag()).executes(commandContext -> spawnEntity((CommandSourceStack)commandContext.getSource(), EntitySummonArgument.getSummonableEntity((CommandContext<CommandSourceStack>)commandContext, "entity"), Vec3Argument.getVec3((CommandContext<CommandSourceStack>)commandContext, "pos"), CompoundTagArgument.getCompoundTag((com.mojang.brigadier.context.CommandContext<Object>)commandContext, "nbt"), false))))));
    }
    
    private static int spawnEntity(final CommandSourceStack cz, final ResourceLocation uh, final Vec3 dem, final CompoundTag le, final boolean boolean5) throws CommandSyntaxException {
        final BlockPos fu6 = new BlockPos(dem);
        if (!Level.isInSpawnableBounds(fu6)) {
            throw SummonCommand.INVALID_POSITION.create();
        }
        final CompoundTag le2 = le.copy();
        le2.putString("id", uh.toString());
        final ServerLevel zd8 = cz.getLevel();
        final ServerLevel serverLevel;
        final Entity aom2 = EntityType.loadEntityRecursive(le2, (Level)zd8, aom -> {
            aom.moveTo(dem.x, dem.y, dem.z, aom.yRot, aom.xRot);
            if (!serverLevel.addWithUUID(aom)) {
                return null;
            }
            else {
                return aom;
            }
        });
        if (aom2 == null) {
            throw SummonCommand.ERROR_FAILED.create();
        }
        if (boolean5 && aom2 instanceof Mob) {
            ((Mob)aom2).finalizeSpawn(cz.getLevel(), cz.getLevel().getCurrentDifficultyAt(aom2.blockPosition()), MobSpawnType.COMMAND, null, null);
        }
        cz.sendSuccess(new TranslatableComponent("commands.summon.success", new Object[] { aom2.getDisplayName() }), true);
        return 1;
    }
    
    static {
        ERROR_FAILED = new SimpleCommandExceptionType((Message)new TranslatableComponent("commands.summon.failed"));
        INVALID_POSITION = new SimpleCommandExceptionType((Message)new TranslatableComponent("commands.summon.invalidPosition"));
    }
}
