package top.quantic.sentry.job;

import com.codahale.metrics.MetricRegistry;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import sx.blah.discord.api.IDiscordClient;
import sx.blah.discord.api.IShard;
import sx.blah.discord.handle.obj.IGuild;
import sx.blah.discord.handle.obj.StatusType;
import top.quantic.sentry.discord.core.ClientRegistry;
import top.quantic.sentry.domain.Bot;

import java.util.Map;
import java.util.concurrent.TimeUnit;

public class BotCheck implements Job {

    private static final Logger log = LoggerFactory.getLogger(BotCheck.class);

    @Autowired
    private ClientRegistry clientRegistry;

    @Autowired
    private MetricRegistry metricRegistry;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        for (Map.Entry<Bot, IDiscordClient> entry : clientRegistry.getClients().entrySet()) {
            IDiscordClient client = entry.getValue();
            if (client.isReady()) {
                String botTag = "bot:" + entry.getKey().getName();
                for (IShard shard : client.getShards()) {
                    String shardTag = "shard:" + shard.getInfo()[0];
                    long millis = shard.getResponseTime();
                    log.debug("[{}:{}] Discord WS response time: {} ms", entry.getKey().getName(), shard.getInfo()[0], millis);
                    metricRegistry.timer("discord.ws.response[" + botTag + "," + shardTag + "]")
                        .update(millis, TimeUnit.MILLISECONDS);
                }
                for (IGuild guild : client.getGuilds()) {
                    String guildTag = "guild:" + guild.getID();
                    long online = guild.getUsers().stream()
                        .filter(user -> user.getPresence().getStatus() == StatusType.ONLINE)
                        .count();
                    long other = guild.getUsers().size() - online;
                    String onlineMetric = "discord.ws.users[" + botTag + "," + guildTag + "," + "status:online]";
                    String otherMetric = "discord.ws.users[" + botTag + "," + guildTag + "," + "status:other]";
                    metricRegistry.histogram(onlineMetric).update(online);
                    metricRegistry.histogram(otherMetric).update(other);
                }
            }
        }
    }
}

@@ -2028,21 +2028,25 @@
    long 
-other
+connected
  = guild
@@ -2062,22 +2062,201 @@
 ().s
-ize() - online
+tream()%0A                        .filter(user -%3E user.getPresence().getStatus() != StatusType.OFFLINE)%0A                        .count();%0A                    long joined = guild.getUsers().size()
 ;%0A  
@@ -2394,21 +2394,25 @@
  String 
-other
+connected
 Metric =
@@ -2474,21 +2474,139 @@
 %22status:
-other
+connected%5D%22;%0A                    String joinedMetric = %22discord.ws.users%5B%22 + botTag + %22,%22 + guildTag + %22,%22 + %22status:joined
 %5D%22;%0A    
@@ -2721,21 +2721,25 @@
 stogram(
-other
+connected
 Metric).
@@ -2749,13 +2749,92 @@
 ate(
-other
+connected);%0A                    metricRegistry.histogram(joinedMetric).update(joined
 );%0A 

Improve user count metric collection