Passed
Push — master ( 2f2f80...76d58f )
by Roannel Fernández
02:54
created

getAvailableFreeCommands()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
dl 0
loc 2
rs 10
c 1
b 0
f 0
cc 1
1
package com.github.netkorp.telegram.framework.managers;
2
3
import com.github.netkorp.telegram.framework.annotations.TelegramCommand;
4
import com.github.netkorp.telegram.framework.bots.PollingTelegramBot;
5
import com.github.netkorp.telegram.framework.commands.interfaces.CloseCommand;
6
import com.github.netkorp.telegram.framework.commands.interfaces.Command;
7
import com.github.netkorp.telegram.framework.commands.interfaces.DoneCommand;
8
import com.github.netkorp.telegram.framework.commands.interfaces.HelpCommand;
9
import com.github.netkorp.telegram.framework.commands.interfaces.MultistageCommand;
10
import com.github.netkorp.telegram.framework.exceptions.CommandNotActive;
11
import com.github.netkorp.telegram.framework.exceptions.CommandNotFound;
12
import org.springframework.beans.factory.annotation.Autowired;
13
import org.springframework.beans.factory.annotation.Value;
14
import org.springframework.stereotype.Component;
15
16
import java.util.Arrays;
17
import java.util.Collection;
18
import java.util.HashMap;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Optional;
22
23
@Component
24
public class CommandManager {
25
    private final Map<String, Command> commands;
26
    private final Map<String, Command> freeCommands;
27
28
    private final Map<Long, MultistageCommand> activeCommand;
29
30
    private String closeCommand;
31
    private String doneCommand;
32
    private String helpCommand;
33
34
    @Autowired
35
    public CommandManager(List<Command> commands, PollingTelegramBot bot, @Value("${telegram.commands.free}") String freeCommands) {
36
        this.commands = new HashMap<>();
37
        this.freeCommands = new HashMap<>();
38
39
        this.activeCommand = new HashMap<>();
40
41
        commands.stream()
42
                .filter(item -> item.getClass().isAnnotationPresent(TelegramCommand.class))
43
                .forEach(command -> addCommand(command, bot, Arrays.asList(freeCommands.split(","))));
44
    }
45
46
    private void addCommand(Command command, PollingTelegramBot bot, List<String> freeCommandNames) {
47
        command.setBot(bot);
48
        command.setCommandManager(this);
49
        this.commands.put(getCommand(command), command);
50
51
        if (isFreeCommand(command, freeCommandNames)) {
52
            this.freeCommands.put(getCommand(command), command);
53
        }
54
55
        if (command instanceof CloseCommand) {
56
            closeCommand = getCommand(command);
57
        } else if (command instanceof DoneCommand) {
58
            doneCommand = getCommand(command);
59
        } else if (command instanceof HelpCommand) {
60
            helpCommand = getCommand(command);
61
        }
62
    }
63
64
    private boolean isFreeCommand(Command command, List<String> freeCommandNames) {
65
        return freeCommandNames.contains(getCommandName(command))
66
                || freeCommandNames.contains(getCommand(command))
67
                || command.getClass().getAnnotation(TelegramCommand.class).free();
68
    }
69
70
    @SuppressWarnings("WeakerAccess")
71
    public static String getCommandName(Command command) {
72
        return command.getClass().getAnnotation(TelegramCommand.class).name();
73
    }
74
75
    public static String getCommand(Command command) {
76
        String commandName = getCommandName(command);
77
        return commandName.startsWith("/") ? commandName : String.format("/%s", commandName);
78
    }
79
80
    /**
81
     * Returns the {@link Command} instance from a given getName.
82
     *
83
     * @param command The commands as {@link String}.
84
     * @return The {@link Command} instance.
85
     * @throws CommandNotFound If the given name is not related to any commands.
86
     */
87
    public Command getCommand(String command) throws CommandNotFound {
88
        if (!this.commands.containsKey(command)) {
89
            throw new CommandNotFound();
90
        }
91
92
        return this.commands.get(command);
93
    }
94
95
    public Command getFreeCommand(String command) throws CommandNotFound {
96
        if (!this.freeCommands.containsKey(command)) {
97
            throw new CommandNotFound();
98
        }
99
100
        return this.freeCommands.get(command);
101
    }
102
103
    public void setActiveCommand(final Long idChat, final MultistageCommand command) {
104
        this.activeCommand.put(idChat, command);
105
    }
106
107
    /**
108
     * Gets the active commands for a given user.
109
     *
110
     * @param idChat Chat id of the user.
111
     * @return The active commands.
112
     */
113
    public MultistageCommand getActiveCommand(Long idChat) throws CommandNotActive {
114
        if (!hasActiveCommand(idChat)) {
115
            throw new CommandNotActive();
116
        }
117
118
        return activeCommand.get(idChat);
119
    }
120
121
    /**
122
     * Removes the active commands.
123
     *
124
     * @param idChat Chat id of the user.
125
     */
126
    public void removeActiveCommand(Long idChat) {
127
        activeCommand.remove(idChat);
128
    }
129
130
    /**
131
     * Is there an active commands or not?
132
     *
133
     * @param idChat Chat id of the user.
134
     * @return If there is active commands or not.
135
     */
136
    public boolean hasActiveCommand(Long idChat) {
137
        return activeCommand.containsKey(idChat);
138
    }
139
140
    /**
141
     * Returns the {@link CloseCommand} if it exists.
142
     *
143
     * @return The {@link CloseCommand} instance.
144
     */
145
    public Optional<Command> getCloseCommand() {
146
        try {
147
            return Optional.ofNullable(getCommand(this.closeCommand));
148
        } catch (CommandNotFound commandNotFound) {
149
            return Optional.empty();
150
        }
151
    }
152
153
    /**
154
     * Returns the {@link DoneCommand} if it exists.
155
     *
156
     * @return The {@link DoneCommand} instance.
157
     */
158
    public Optional<Command> getDoneCommand() {
159
        try {
160
            return Optional.ofNullable(getCommand(this.doneCommand));
161
        } catch (CommandNotFound commandNotFound) {
162
            return Optional.empty();
163
        }
164
    }
165
166
    /**
167
     * Returns the {@link HelpCommand} if it exists.
168
     *
169
     * @return The {@link HelpCommand} instance.
170
     */
171
    public Optional<Command> getHelpCommand() {
172
        try {
173
            return Optional.ofNullable(getCommand(this.helpCommand));
174
        } catch (CommandNotFound commandNotFound) {
175
            return Optional.empty();
176
        }
177
    }
178
179
    /**
180
     * Returns a list with the available commands.
181
     *
182
     * @return Available commands.
183
     */
184
    public Collection<Command> getAvailableCommands() {
185
        return commands.values();
186
    }
187
188
    /**
189
     * Returns a list with the available free commands.
190
     *
191
     * @return Available free commands.
192
     */
193
    public Collection<Command> getAvailableFreeCommands() {
194
        return freeCommands.values();
195
    }
196
}
197