package tterrag.tppibot.runnables;
import static tterrag.tppibot.util.Logging.*;
import static tterrag.tppibot.util.ThreadUtils.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.Setter;
import lombok.Value;
import lombok.experimental.NonFinal;
import org.pircbotx.Channel;
import org.pircbotx.PircBotX;
import org.pircbotx.hooks.events.DisconnectEvent;
import tterrag.tppibot.Main;
import tterrag.tppibot.config.Config;
import tterrag.tppibot.util.IRCUtils;
import tterrag.tppibot.util.Logging;
import com.google.common.eventbus.Subscribe;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class ReminderProcess implements Runnable {
@Value
private static class RemindTime {
private long init;
@Setter
@NonFinal
private long time;
private int index;
}
private PircBotX bot;
private Map<String, Boolean> reminderMap;
private List<String> reminders;
private Map<String, RemindTime> delayMap;
private Config mapConfig, remindersConfig, delayConfig;
public ReminderProcess(PircBotX bot, String... defaults) {
this.bot = bot;
mapConfig = new Config("reminderMap.json");
remindersConfig = new Config("reminders.json");
delayConfig = new Config("reminderDelays.json");
Gson gson = new Gson();
reminderMap = gson.fromJson(mapConfig.getText(), new TypeToken<Map<String, Boolean>>() {
}.getType());
if (reminderMap == null) {
reminderMap = new HashMap<String, Boolean>();
}
reminders = gson.fromJson(remindersConfig.getText(), new TypeToken<List<String>>() {
}.getType());
if (reminders == null) {
reminders = new LinkedList<String>();
for (String s : defaults) {
reminders.add(s);
}
}
delayMap = gson.fromJson(delayConfig.getText(), new TypeToken<Map<String, RemindTime>>() {
}.getType());
if (delayMap == null) {
delayMap = new HashMap<String, RemindTime>();
}
}
@Override
public void run() {
while (true) {
try {
sleep(1000);
if (bot.isConnected() && !bot.getUserChannelDao().getAllChannels().isEmpty()) {
long time = System.currentTimeMillis();
for (Channel channel : bot.getUserBot().getChannels()) {
RemindTime remind = delayMap.get(channel.getName());
if (Main.reminderCommand.delayMap.get(channel.getName()) == null) {
Main.reminderCommand.delayMap.put(channel.getName(), 900000L);
}
if (remind == null) {
delayMap.put(channel.getName(), new RemindTime(time, Main.reminderCommand.delayMap.get(channel.getName()), 0));
}
String reminder = reminders.get(remind.getIndex() % reminders.size()); // make sure removal hasn't shifted indeces
if (time - remind.getInit() > remind.getTime() && isRemindEnabledFor(channel.getName())) {
remind(channel, reminder);
delayMap.put(channel.getName(), new RemindTime(time, Main.reminderCommand.delayMap.get(channel.getName()), nextIndex(remind.getIndex())));
}
}
} else {
log("Bot not connected, waiting...");
sleep(10000);
}
} catch (Throwable t) {
t.printStackTrace();
Logging.error("An error occured with the Reminder Process, continuing...");
sleep(10000);
}
}
}
private int nextIndex(int index) {
return (index + 1) % reminders.size();
}
private void remind(Channel channel, String reminder) {
synchronized (reminders) {
log("Sending reminder!");
channel.getBot().sendIRC().message(channel.getName(), reminder);
}
}
public void addReminder(String reminder) {
synchronized (reminders) {
reminders.add(reminder);
}
}
public void removeReminder(int index) {
reminders.remove(index);
}
public void disableRemindersFor(String channel) {
reminderMap.put(channel.toLowerCase(), false);
}
public void enableRemindersFor(String channel) {
reminderMap.put(channel.toLowerCase(), true);
}
public boolean isRemindEnabledFor(String channel) {
channel = IRCUtils.fmtChan(channel);
return channel == null ? false : reminderMap.get(channel.toLowerCase());
}
public boolean isInReminderMap(String channel) {
channel = IRCUtils.fmtChan(channel);
return reminderMap.containsKey(channel.toLowerCase());
}
@Subscribe
public void onDisconnect(DisconnectEvent<PircBotX> event) {
mapConfig.writeJsonToFile(reminderMap);
remindersConfig.writeJsonToFile(reminders);
delayConfig.writeJsonToFile(delayMap);
}
public void setDelay(String name, long millis) {
if (delayMap.get(name) == null) {
delayMap.put(name, new RemindTime(System.currentTimeMillis(), millis, 0));
} else {
delayMap.get(name).setTime(millis);
}
}
public String[] getReminders() {
return reminders.toArray(new String[] {});
}
}