package top.quantic.sentry.job;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.ibasco.agql.protocols.valve.steam.webapi.pojos.SteamPlayerProfile;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import top.quantic.sentry.service.GameQueryService;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class SteamProfilePoller implements Job {

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

    @Autowired
    private GameQueryService gameQueryService;

    @Autowired
    private MetricRegistry metricRegistry;

    private final Map<Long, SteamPlayerProfile> profileMap = new ConcurrentHashMap<>();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getMergedJobDataMap();
        String keys = dataMap.getString("keys");
        if (keys == null) {
            throw new JobExecutionException("Data map key 'keys' is missing");
        }

        Set<Long> checked = new LinkedHashSet<>();

        for (String key : keys.split(";")) {
            Long id = gameQueryService.getSteamId64(key).exceptionally(t -> {
                log.warn("Could not get profile ID from key {}", key, t);
                return null;
            }).join();
            if (id != null) {
                profileMap.put(id, getPlayerProfile(id));
                registerGauges(id);
                checked.add(id);
            }
        }

        // clean up removed ids
        metricRegistry.removeMatching((name, metric) -> name.startsWith("steam.profile") && !checked.contains(extractId(name)));
    }

    private Long extractId(String name) {
        return Long.valueOf(name.replaceAll("^steam\\.profile\\..+\\[steamId:([0-9]+)]$", "$1"));
    }

    private void registerGauges(Long id) {
        if (metricRegistry.getGauges((name, metric) -> name.contains("steamId:" + id)).isEmpty()) {
            metricRegistry.register("steam.profile.status[steamId:" + id + "]", (Gauge<Integer>) () -> profileMap.get(id).getPersonaState());
            metricRegistry.register("steam.profile.lastLogOff[steamId:" + id + "]", (Gauge<Long>) () -> profileMap.get(id).getLastLogOff());
        }
    }

    private SteamPlayerProfile getPlayerProfile(Long id) {
        return gameQueryService.getPlayerProfile(id).exceptionally(t -> {
            log.warn("Could not retrieve profile info for {}", id, t);
            SteamPlayerProfile dummy = new SteamPlayerProfile();
            dummy.setPersonaState(0);
            dummy.setLastLogOff(0);
            return dummy;
        }).join();
    }
}

@@ -542,80 +542,11 @@
 til.
-Map;%0Aimport java.util.Set;%0Aimport java.util.concurrent.ConcurrentHashMap
+Set
 ;%0A%0Ap
@@ -810,97 +810,8 @@
 y;%0A%0A
-    private final Map%3CLong, SteamPlayerProfile%3E profileMap = new ConcurrentHashMap%3C%3E();%0A%0A
     
@@ -1482,21 +1482,13 @@
     
-profileMap.pu
+repor
 t(id
@@ -1516,44 +1516,8 @@
 ));%0A
-                registerGauges(id);%0A
     
@@ -1908,168 +1908,154 @@
 d re
-gisterGauges(Long id) %7B%0A        if (metricRegistry.getGauges((name, metric) -%3E name.contains(%22steamId:%22 + id)).isEmpty()) %7B%0A            metricRegistry.register(
+port(Long id, SteamPlayerProfile profile) %7B%0A        String statusKey = %22steam.profile.status%5BsteamId:%22 + id + %22%5D%22;%0A        String lastLogOffKey = 
 %22ste
@@ -2057,38 +2057,42 @@
  %22steam.profile.
-status
+lastLogOff
 %5BsteamId:%22 + id 
@@ -2088,32 +2088,117 @@
 mId:%22 + id + %22%5D%22
+;%0A        metricRegistry.remove(statusKey);%0A        metricRegistry.register(statusKey
 , (Gauge%3CInteger
@@ -2199,30 +2199,24 @@
 nteger%3E)
- () -%3E
  profile
 Map.get(
@@ -2207,28 +2207,18 @@
  profile
-Map.get(id).
+::
 getPerso
@@ -2224,18 +2224,16 @@
 onaState
-()
 );%0A     
@@ -2239,82 +2239,91 @@
     
-    metricRegistry.register(%22steam.profile.lastLogOff%5BsteamId:%22 + id + %22%5D%22
+metricRegistry.remove(lastLogOffKey);%0A        metricRegistry.register(lastLogOffKey
 , (G
@@ -2337,22 +2337,16 @@
 ng%3E)
- () -%3E
  profile
 Map.
@@ -2345,20 +2345,10 @@
 file
-Map.get(id).
+::
 getL
@@ -2360,22 +2360,10 @@
 gOff
-());%0A        %7D
+);
 %0A   

Remove cached profiles map