package net.minecraft.command.server;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.CommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.PlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.stats.Achievement;
import net.minecraft.stats.AchievementList;
import net.minecraft.stats.StatBase;
import net.minecraft.stats.StatList;
import net.minecraft.util.BlockPos;

public class CommandAchievement extends CommandBase
{
    /**
     * Gets the name of the command
     */
    public String getCommandName()
    {
        return "achievement";
    }

    /**
     * Return the required permission level for this command.
     */
    public int getRequiredPermissionLevel()
    {
        return 2;
    }

    /**
     * Gets the usage string for the command.
     */
    public String getCommandUsage(CommandSender sender)
    {
        return "commands.achievement.usage";
    }

    /**
     * Callback when the command is invoked
     */
    public void processCommand(CommandSender sender, String[] args) throws CommandException
    {
        if (args.length < 2)
        {
            throw new WrongUsageException("commands.achievement.usage", new Object[0]);
        }
        else
        {
            final StatBase statbase = StatList.getOneShotStat(args[1]);

            if (statbase == null && !args[1].equals("*"))
            {
                throw new CommandException("commands.achievement.unknownAchievement", new Object[] {args[1]});
            }
            else
            {
                final PlayerMP entityplayermp = args.length >= 3 ? getPlayer(sender, args[2]) : getCommandSenderAsPlayer(sender);
                boolean flag = args[0].equalsIgnoreCase("give");
                boolean flag1 = args[0].equalsIgnoreCase("take");

                if (flag || flag1)
                {
                    if (statbase == null)
                    {
                        if (flag)
                        {
                            for (Achievement achievement4 : AchievementList.achievementList)
                            {
                                entityplayermp.triggerAchievement(achievement4);
                            }

                            notifyOperators(sender, this, "commands.achievement.give.success.all", new Object[] {entityplayermp.getName()});
                        }
                        else if (flag1)
                        {
                            for (Achievement achievement5 : Lists.reverse(AchievementList.achievementList))
                            {
                                entityplayermp.func_175145_a(achievement5);
                            }

                            notifyOperators(sender, this, "commands.achievement.take.success.all", new Object[] {entityplayermp.getName()});
                        }
                    }
                    else
                    {
                        if (statbase instanceof Achievement)
                        {
                            Achievement achievement = (Achievement)statbase;

                            if (flag)
                            {
                                if (entityplayermp.getStatFile().hasAchievementUnlocked(achievement))
                                {
                                    throw new CommandException("commands.achievement.alreadyHave", new Object[] {entityplayermp.getName(), statbase.func_150955_j()});
                                }

                                List<Achievement> list;

                                for (list = Lists.<Achievement>newArrayList(); achievement.parentAchievement != null && !entityplayermp.getStatFile().hasAchievementUnlocked(achievement.parentAchievement); achievement = achievement.parentAchievement)
                                {
                                    list.add(achievement.parentAchievement);
                                }

                                for (Achievement achievement1 : Lists.reverse(list))
                                {
                                    entityplayermp.triggerAchievement(achievement1);
                                }
                            }
                            else if (flag1)
                            {
                                if (!entityplayermp.getStatFile().hasAchievementUnlocked(achievement))
                                {
                                    throw new CommandException("commands.achievement.dontHave", new Object[] {entityplayermp.getName(), statbase.func_150955_j()});
                                }

                                List<Achievement> list1 = Lists.newArrayList(Iterators.filter(AchievementList.achievementList.iterator(), new Predicate<Achievement>()
                                {
                                    public boolean apply(Achievement p_apply_1_)
                                    {
                                        return entityplayermp.getStatFile().hasAchievementUnlocked(p_apply_1_) && p_apply_1_ != statbase;
                                    }
                                }));
                                List<Achievement> list2 = Lists.newArrayList(list1);

                                for (Achievement achievement2 : list1)
                                {
                                    Achievement achievement3 = achievement2;
                                    boolean flag2;

                                    for (flag2 = false; achievement3 != null; achievement3 = achievement3.parentAchievement)
                                    {
                                        if (achievement3 == statbase)
                                        {
                                            flag2 = true;
                                        }
                                    }

                                    if (!flag2)
                                    {
                                        for (achievement3 = achievement2; achievement3 != null; achievement3 = achievement3.parentAchievement)
                                        {
                                            list2.remove(achievement2);
                                        }
                                    }
                                }

                                for (Achievement achievement6 : list2)
                                {
                                    entityplayermp.func_175145_a(achievement6);
                                }
                            }
                        }

                        if (flag)
                        {
                            entityplayermp.triggerAchievement(statbase);
                            notifyOperators(sender, this, "commands.achievement.give.success.one", new Object[] {entityplayermp.getName(), statbase.func_150955_j()});
                        }
                        else if (flag1)
                        {
                            entityplayermp.func_175145_a(statbase);
                            notifyOperators(sender, this, "commands.achievement.take.success.one", new Object[] {statbase.func_150955_j(), entityplayermp.getName()});
                        }
                    }
                }
            }
        }
    }

    public List<String> addTabCompletionOptions(CommandSender sender, String[] args, BlockPos pos)
    {
        if (args.length == 1)
        {
            return getListOfStringsMatchingLastWord(args, new String[] {"give", "take"});
        }
        else if (args.length != 2)
        {
            return args.length == 3 ? getListOfStringsMatchingLastWord(args, MinecraftServer.getServer().getAllUsernames()) : null;
        }
        else
        {
            List<String> list = Lists.<String>newArrayList();

            for (StatBase statbase : StatList.allStats)
            {
                list.add(statbase.statId);
            }

            return getListOfStringsMatchingLastWord(args, list);
        }
    }

    /**
     * Return whether the specified command parameter index is a username parameter.
     */
    public boolean isUsernameIndex(String[] args, int index)
    {
        return index == 2;
    }
}
