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

package com.hypixel.hytale.server.core.modules.accesscontrol.commands;

import java.util.Map;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.util.UUID;
import java.util.Optional;
import com.hypixel.hytale.server.core.modules.accesscontrol.ban.InfiniteBan;
import java.time.Instant;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.CommandUtil;
import java.util.concurrent.CompletableFuture;
import com.hypixel.hytale.server.core.command.system.CommandContext;
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.auth.ProfileServiceClient;
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.modules.accesscontrol.provider.HytaleBanProvider;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncCommand;

public class BanCommand extends AbstractAsyncCommand
{
    @Nonnull
    private final HytaleBanProvider banProvider;
    @Nonnull
    private final RequiredArg<ProfileServiceClient.PublicGameProfile> playerArg;
    
    public BanCommand(@Nonnull final HytaleBanProvider banProvider) {
        super("ban", "server.commands.ban.desc");
        this.playerArg = this.withRequiredArg("player", "server.commands.ban.player.desc", ArgTypes.GAME_PROFILE_LOOKUP);
        this.setUnavailableInSingleplayer(true);
        this.banProvider = banProvider;
    }
    
    @Nonnull
    @Override
    protected CompletableFuture<Void> executeAsync(@Nonnull final CommandContext context) {
        final ProfileServiceClient.PublicGameProfile profile = this.playerArg.get(context);
        if (profile == null) {
            return CompletableFuture.completedFuture((Void)null);
        }
        final UUID uuid = profile.getUuid();
        final String rawArgs = CommandUtil.stripCommandName(context.getInputString());
        final int firstSpaceIndex = rawArgs.indexOf(32);
        String reason;
        if (firstSpaceIndex != -1) {
            final String afterPlayer = rawArgs.substring(firstSpaceIndex + 1).trim();
            reason = (afterPlayer.isEmpty() ? "No reason." : afterPlayer);
        }
        else {
            reason = "No reason.";
        }
        final Message displayMessage = Message.raw(profile.getUsername()).bold(true);
        final PlayerRef playerRef = Universe.get().getPlayer(uuid);
        if (this.banProvider.hasBan(uuid)) {
            context.sendMessage(Message.translation("server.modules.ban.alreadyBanned").param("name", displayMessage));
            return CompletableFuture.completedFuture((Void)null);
        }
        final InfiniteBan ban = new InfiniteBan(uuid, context.sender().getUuid(), Instant.now(), reason);
        this.banProvider.modify(banMap -> {
            banMap.put(uuid, ban);
            return Boolean.TRUE;
        });
        if (playerRef != null) {
            final CompletableFuture<Optional<String>> disconnectReason = ban.getDisconnectReason(uuid);
            return disconnectReason.whenComplete((string, disconnectEx) -> {
                Optional<String> optional = string;
                if (disconnectEx != null) {
                    context.sendMessage(Message.translation("server.modules.ban.failedDisconnectReason").param("name", displayMessage));
                    disconnectEx.printStackTrace();
                }
                if (optional == null || !optional.isPresent()) {
                    optional = Optional.of("Failed to get disconnect reason.");
                }
                playerRef.getPacketHandler().disconnect(optional.get());
                context.sendMessage(Message.translation("server.modules.ban.bannedWithReason").param("name", displayMessage).param("reason", reason));
                return;
            }).thenApply(v -> null);
        }
        context.sendMessage(Message.translation("server.modules.ban.bannedWithReason").param("name", displayMessage).param("reason", reason));
        return CompletableFuture.completedFuture((Void)null);
    }
}
