package com.rai220.securityalarmbot.commands; import com.google.common.collect.ImmutableSet; import com.pengrad.telegrambot.model.Message; import com.pengrad.telegrambot.model.request.Keyboard; import com.rai220.securityalarmbot.BotService; import com.rai220.securityalarmbot.R; import com.rai220.securityalarmbot.exeptions.NoCommandException; import com.rai220.securityalarmbot.prefs.Prefs; import com.rai220.securityalarmbot.telegram.TelegramService; import com.rai220.securityalarmbot.utils.KeyboardUtils; import com.rai220.securityalarmbot.utils.L; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * */ public class CommandHelper { private final BotService botService; private final TelegramService telegramService; /** * Map of registered commands */ private Map<String, ICommand> registeredCommandMap = new HashMap<>(); /** * Map of last user's command * key - User * value - last command */ private Map<Prefs.UserPrefs, ICommand> lastUserCommand = new HashMap<>(); private Keyboard mainKeyboard; public CommandHelper(BotService botService) { this.botService = botService; this.telegramService = botService.getTelegramService(); init(); } public void init() { registeredCommandMap.clear(); lastUserCommand.clear(); Set<Class<? extends AbstractCommand>> existsCommands = ImmutableSet.of( PhotoCommand.class, HDPhotoCommand.class, CameraModeCommand.class, CameraSettingsCommand.class, AlarmSettingsCommand.class, MinutesCommand.class, HistoryCommand.class, MotionDetectCommand.class, MDSensitivityCommand.class, MdModeCommand.class, ShakeSensorCommand.class, ShakeSensitivityCommand.class, GpsCommand.class, NotificationCommand.class, TtsCommand.class, AudioCommand.class, TaskerCommand.class, LogCommand.class, SetMatrixCommand.class, // ProCommand.class, // Temporary disable this function RestartCommand.class, TimeStatsCommand.class, TimeStatsClearCommand.class, StatusCommand.class, HelpCommand.class ); for (Class<? extends AbstractCommand> clazz : existsCommands) { ICommand instance = createInstance(clazz); if (registeredCommandMap.containsKey(instance.getCommand())) { ICommand command = registeredCommandMap.get(instance.getCommand()); L.e("Duplicate of command: " + instance.getCommand() + ", names: [" + instance.getName() + ", " + command.getName() + "]"); } else { registeredCommandMap.put(instance.getCommand(), instance); } } mainKeyboard = KeyboardUtils.getKeyboard(registeredCommandMap.values()); L.i("Count of registered commands: " + registeredCommandMap.size()); } public void executeCommand(Message message, Prefs prefs) throws NoCommandException { final long chatId = message.chat().id(); String text = message.text(); Prefs.UserPrefs user = prefs.getUser(message.from()); ICommand command = findCommand(text); if (command == null) { command = lastUserCommand.get(user); lastUserCommand.remove(user); if (command == null) { throw new NoCommandException(text); } } L.i("Message from " + message.from().username() + ": " + command.getCommand()); if (command.execute(message, prefs)) { lastUserCommand.put(user, command); } else { telegramService.sendMessage(chatId, botService.getString(R.string.please_select_command), mainKeyboard); } } public Keyboard getMainKeyboard() { return mainKeyboard; } public ICommand findCommand(String text) { ICommand command = registeredCommandMap.get(text); if (command == null) { for (ICommand cmd : registeredCommandMap.values()) { if (cmd.getName().equals(text)) { return cmd; } } } return command; } public Collection<ICommand> getRegisteredCommands() { return registeredCommandMap.values(); } private <T extends AbstractCommand> T createInstance(Class<T> clazz) { try { Constructor constructor = clazz.getDeclaredConstructor(BotService.class); constructor.setAccessible(true); return (T) constructor.newInstance(botService); } catch (Exception ex) { L.e(ex); } return null; } }