001package co.aikar.commands;
002
003import co.aikar.commands.annotation.Author;
004import co.aikar.commands.annotation.Optional;
005import co.aikar.commands.annotation.SelfUser;
006import net.dv8tion.jda.core.JDA;
007import net.dv8tion.jda.core.entities.ChannelType;
008import net.dv8tion.jda.core.entities.Guild;
009import net.dv8tion.jda.core.entities.Message;
010import net.dv8tion.jda.core.entities.MessageChannel;
011import net.dv8tion.jda.core.entities.TextChannel;
012import net.dv8tion.jda.core.entities.User;
013import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
014
015import java.util.List;
016
017public class JDACommandContexts extends CommandContexts<JDACommandExecutionContext> {
018    private final JDACommandManager manager;
019    private final JDA jda;
020
021    public JDACommandContexts(JDACommandManager manager) {
022        super(manager);
023        this.manager = manager;
024        this.jda = this.manager.getJDA();
025        this.registerIssuerOnlyContext(JDACommandEvent.class, CommandExecutionContext::getIssuer);
026        this.registerIssuerOnlyContext(MessageReceivedEvent.class, c -> c.getIssuer().getIssuer());
027        this.registerIssuerOnlyContext(Message.class, c -> c.issuer.getIssuer().getMessage());
028        this.registerIssuerOnlyContext(ChannelType.class, c -> c.issuer.getIssuer().getChannelType());
029        this.registerIssuerOnlyContext(JDA.class, c -> jda);
030        this.registerIssuerOnlyContext(Guild.class, c -> {
031            MessageReceivedEvent event = c.getIssuer().getIssuer();
032            if (event.isFromType(ChannelType.PRIVATE) && !c.hasAnnotation(Optional.class)) {
033                throw new InvalidCommandArgument("This command can only be executed in a Guild.", false); // TODO: Message Keys
034            } else {
035                return event.getGuild();
036            }
037        });
038        this.registerIssuerOnlyContext(MessageChannel.class, c -> {
039            if (c.hasAnnotation(Author.class)) {
040                return c.issuer.getIssuer().getChannel();
041            }
042            String argument = c.popFirstArg();
043            MessageChannel channel = null;
044            if (argument.startsWith("<#")) {
045                channel = jda.getTextChannelById(argument.substring(2, argument.length() - 1));
046            } else {
047                List<TextChannel> channelList = c.issuer.getEvent().getGuild().getTextChannelsByName(argument.toLowerCase(), true);
048                if (channelList.size() > 1) {
049                    throw new InvalidCommandArgument("Too many channels were found with the given name. Try with the `#channelname` syntax.", false);
050                } else if (channelList.size() == 1) {
051                    channel = channelList.get(0);
052                }
053            }
054            if (channel == null) {
055                throw new InvalidCommandArgument("Couldn't find the channel with that name or ID.");
056            }
057            return channel;
058        });
059        this.registerContext(User.class, c -> {
060            if (c.hasAnnotation(SelfUser.class)) {
061                return jda.getSelfUser();
062            }
063            String arg = c.popFirstArg();
064            User user = null;
065            if (arg.startsWith("<@")) {
066                user = jda.getUserById(arg.substring(2, arg.length() - 1));
067            } else {
068                List<User> users = jda.getUsersByName(arg, true);
069                if (users.size() > 1) {
070                    throw new InvalidCommandArgument("Too many users were found with the given name. Try with the `@username#0000` syntax.", false);
071                }
072                if (!users.isEmpty()) {
073                    user = users.get(0);
074                }
075            }
076            if (user == null) {
077                throw new InvalidCommandArgument("Could not find a user with that name or ID"); // TODO: Message keys
078            }
079            return user;
080        });
081    }
082}