package com.github.games647.lagmonitor.task;

import com.github.games647.lagmonitor.ping.PingFetcher;
import com.github.games647.lagmonitor.ping.ReflectionPing;
import com.github.games647.lagmonitor.util.RollingOverHistory;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;

public class PingManager implements Runnable, Listener {

    //the server is pinging the client every 40 Ticks (2 sec) - so check it then
    //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
    public static final int PING_INTERVAL = 2 * 20;
    private static final int SAMPLE_SIZE = 5;

    private final Map<String, RollingOverHistory> playerHistory = new HashMap<>();
    private final Plugin plugin;
    private final PingFetcher pingFetcher;

    public PingManager(Plugin plugin) throws ReflectiveOperationException {
        this.pingFetcher = initializePingFetchur();
        this.plugin = plugin;
    }

    private PingFetcher initializePingFetchur()
            throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // List<Class<? extends PingFetcher>> fetchurs = Lists.newArrayList(
        //         SpigotPing.class, PaperPing.class, ReflectionPing.class
        // );
        // for (Class<? extends PingFetcher> fetchurClass : fetchurs) {
        //     PingFetcher fetchur = fetchurClass.getDeclaredConstructor().newInstance();
        //     if (fetchur.isAvailable())
        //         return fetchur;
        // }
        return new ReflectionPing();

        // throw new NoSuchMethodException("No valid ping fetcher found");
    }

    @Override
    public void run() {
        playerHistory.forEach((playerName, history) -> {
            Player player = Bukkit.getPlayerExact(playerName);
            if (player != null) {
                int ping = pingFetcher.getPing(player);
                history.add(ping);
            }
        });
    }

    public RollingOverHistory getHistory(String playerName) {
        return playerHistory.get(playerName);
    }

    public void addPlayer(Player player) {
        int ping = pingFetcher.getPing(player);
        playerHistory.put(player.getName(), new RollingOverHistory(SAMPLE_SIZE, ping));
    }

    public void removePlayer(Player player) {
        playerHistory.remove(player.getName());
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent joinEvent) {
        Player player = joinEvent.getPlayer();
        Bukkit.getScheduler().runTaskLater(plugin, () -> {
            if (player.isOnline()) {
                addPlayer(player);
            }
        }, PING_INTERVAL);
    }

    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent quitEvent) {
        removePlayer(quitEvent.getPlayer());
    }

    public void clear() {
        playerHistory.clear();
    }
}

@@ -39,16 +39,70 @@
 .task;%0A%0A
+import com.github.games647.lagmonitor.ping.PaperPing;%0A
 import c
@@ -145,24 +145,24 @@
 ingFetcher;%0A
-
 import com.g
@@ -204,24 +204,79 @@
 ectionPing;%0A
+import com.github.games647.lagmonitor.ping.SpigotPing;%0A
 import com.g
@@ -325,16 +325,56 @@
 History;
+%0Aimport com.google.common.collect.Lists;
 %0A%0Aimport
@@ -419,16 +419,16 @@
 eption;%0A
-
 import j
@@ -445,16 +445,39 @@
 ashMap;%0A
+import java.util.List;%0A
 import j
@@ -1598,19 +1598,16 @@
 %0A       
- //
  List%3CCl
@@ -1664,35 +1664,32 @@
 rayList(%0A       
- //
          SpigotP
@@ -1744,19 +1744,16 @@
 %0A       
- //
  );%0A    
@@ -1755,19 +1755,16 @@
 %0A       
- //
  for (Cl
@@ -1820,27 +1820,24 @@
 s) %7B%0A       
- //
      PingFet
@@ -1907,27 +1907,24 @@
 e();%0A       
- //
      if (fet
@@ -1950,19 +1950,16 @@
 %0A       
- //
         
@@ -1987,49 +1987,9 @@
     
-// %7D%0A        return new ReflectionPing();
+%7D
 %0A%0A  
@@ -1993,19 +1993,16 @@
 %0A       
- //
  throw n

Fix missing ping fetchers