package jnet.server;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jnet.lib.BuilddDate;
import jnet.lib.LogFile;
import jnet.lib.LogWindow;
import jnet.lib.OSValidator;
import jnet.lib.PropertiesManager;
import jnet.lib.object.Event;
import jnet.lib.object.Map;
import jnet.lib.object.ObjectType;
import jnet.lib.object.OnlineClients;
import jnet.lib.object.SnmpProbe;
import jnet.lib.object.SnmpProfile;
import jnet.lib.object.User;
import jnet.lib.snmp.SNMPTrafficMonitor;
import jnet.server.network.NettyServer;
import jnet.server.probe.NettyPing;

public class Server {

    // verze serveru
    public static final int SERVER_VERSION = 1;

    // minimální verze klienta
    public static final int MINIMAL_CLIENT_VERSION = 1;

    public static PropertiesManager config;
    public static List<Map> maps = new ArrayList<>();
    public static List<OnlineClients> onlineClients = new ArrayList<>();
    public static List<ObjectType> objectType = new ArrayList<>();
    public static List<SnmpProfile> snmpProfile = new ArrayList<>();
    public static List<SnmpProbe> snmpProbe = new ArrayList<>();
    public static List<User> users = new ArrayList<>();
    public static List<Event> events = new ArrayList<>();

    public static void main(String[] args) {

//        // Zde můžete zadat index rozhraní, které chcete monitorovat (např. 1 pro eth0)
//        int interfaceIndex = 1;
//
//        // Vytvoření instance monitoru pro zadaný index rozhraní
//        try {
//            SNMPTrafficMonitor monitor = new SNMPTrafficMonitor("10.0.0.16", "161", "public", 0);
//            monitor.startMonitoring(interfaceIndex);
//
//            // Po 60 sekundách zastavíme monitoring
//            Thread.sleep(60000);  // Monitoring běží 60 sekund
//            monitor.stopMonitoring();
//            monitor.stop();
//        } catch (Exception ex) {
//            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
//        }

        // pokud je hostitelsky system windows otevre logovaci okno
        if (OSValidator.isWindows()) {
            new LogWindow();
        }

        LogFile.clear();
        LogFile.setDebug(false);
        LogFile.printInfo("---------------------------------------------");
        LogFile.printInfo("                jNet Server            ");
        LogFile.printInfo(" Version: " + SERVER_VERSION + " (" + BuilddDate.get() + ")");
        LogFile.printInfo("---------------------------------------------");
        LogFile.printInfo("");

        ///
        /// nahrani konfigurace
        ///
        LogFile.printInfo("Loading config ...");
        try {
            // Načtení existující konfigurace, pokud soubor existuje
            config = new PropertiesManager("config.properties");
            config.load();
            LogFile.printInfo("     successfully");
        } catch (PropertiesManager.FileException | PropertiesManager.ConfigException ex) {
            LogFile.printErr("     fail. " + ex.getMessage());
            System.exit(0);
        }

        ///
        /// debug rezim ?
        ///
        if (config.getBoolean("debug")) {
            LogFile.setDebug(true);
            LogFile.printDebug("Debug mode on");
        }

        ///
        /// pripojeni k databazi
        ///
        new Database().connect(config.getString("mysql_server"),
                config.getString("mysql_port"),
                config.getString("mysql_database"),
                config.getString("mysql_user"),
                config.getString("mysql_password"));

        ///
        /// konfigurace z databaze
        ///
        LogFile.printInfo("Loading user list ...");
        users = Database.getUsers();
        LogFile.printInfo("    load " + users.size() + " user(s)");

        LogFile.printInfo("Loading map list ...");
        maps = Database.getMapList();
        LogFile.printInfo("    load " + maps.size() + " map(s)");

        LogFile.printInfo("Loading object type ...");
        objectType = Database.getObjectType();
        LogFile.printInfo("    load " + objectType.size() + " type(s)");

        LogFile.printInfo("Loading SNMP profile ...");
        snmpProfile = Database.getSnmpProfile();
        LogFile.printInfo("    load " + snmpProfile.size() + " profile(s)");

//        LogFile.printInfo("Loading SNMP template ...");
//        snmpProbe = Database.getSnmpProbe();
//        LogFile.printInfo("    load " + snmpProbe.size() + " template(s)");
        LogFile.printInfo("Loading events ...");
        events = Database.getEvents();
        LogFile.printInfo("    load " + events.size() + " event(s)");

        ///
        /// spusteni serveru
        ///
        NettyServer nettyserver = new NettyServer(config.getInt("server_port"));
        nettyserver.start();

        ///
        /// spusteni ping probe 
        ///
        /// spousete pro kazdou mapu samostatne ? 
        /// 
//        Ping pp = new Ping();
//        pp.start();

//        Ping2 p2 = new Ping2();
//        p2.start();

          NettyPing np = new NettyPing();
        np.start();

    }

    public static void restartServer() {
        new Thread(() -> {
            try {
                Thread.sleep(5000);
                try {
                    String java = System.getProperty("java.home") + "/bin/java";
                    File jarFile = new File(Server.class
                            .getProtectionDomain().getCodeSource().getLocation().getPath());

                    List<String> command = new ArrayList<>();
                    command.add(java);
                    command.add("-jar");
                    command.add(jarFile.getAbsolutePath());

                    new ProcessBuilder(command).start();
                    System.exit(0);
                } catch (IOException ex) {
                    LogFile.printErr("Restart failed! " + ex.getMessage());
                }
            } catch (InterruptedException e) {
                LogFile.printErr("Restart failed! " + e.getMessage());
            }
        }).start();
    }

}
