// Path: localnet/src/main/java/dev/jokr/localnet/discovery/models/DiscoveryReply.java
// public class DiscoveryReply implements Serializable {
// 
//     private String ip;
//     private int port;
// 
//     public DiscoveryReply(String ip, int port) {
//         this.ip = ip;
//         this.port = port;
//     }
// 
//     public String getIp() {
//         return ip;
//     }
// 
//     public int getPort() {
//         return port;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/ConnectedClients.java
// public class ConnectedClients {
// 
//     private HashMap<Long, RegisterMessage> registeredClients;
// 
//     public ConnectedClients(HashMap<Long, RegisterMessage> registeredClients) {
//         this.registeredClients = registeredClients;
//     }
// 
//     public Payload<?> getPayload(int clientId) {
//         if (registeredClients.containsKey(clientId))
//             return registeredClients.get(clientId).getPayload();
//         else
//             return null;
//     }
// 
//     public Set<Long> getAllClientsIds() {
//         return registeredClients.keySet();
//     }
// 
//     public int getClientsSize() {
//         return registeredClients.size();
//     }
// 
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/Payload.java
// public class Payload<T> implements Serializable {
// 
//     private T payload;
// 
//     public Payload(T payload) {
//         this.payload = payload;
//     }
// 
//     public T getPayload() {
//         return payload;
//     }
// 
// 
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/RegisterMessage.java
// public class RegisterMessage implements Serializable {
// 
//     private Payload<?> payload;
//     private String ip;
//     private int port;
// 
//     public RegisterMessage(Payload<?> payload, String ip, int port) {
//         this.payload = payload;
//         this.ip = ip;
//         this.port = port;
//     }
// 
//     public String getIp() {
//         return ip;
//     }
// 
//     public int getPort() {
//         return port;
//     }
// 
//     public Payload<?> getPayload() {
//         return payload;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/SessionMessage.java
// public class SessionMessage implements Serializable {
// 
//     public static final int NONE = 0;
//     public static final int START = 1;
//     public static final int END = 2;
// 
//     private Payload<?> payload;
//     private int signal;
// 
// 
//     public SessionMessage(Payload<?> payload) {
//         this.payload = payload;
//         this.signal = NONE;
//     }
// 
//     public SessionMessage(Payload<?> payload, int signal) {
//         this.payload = payload;
//         this.signal = signal;
//     }
// 
//     public int getSignal() {
//         return signal;
//     }
// 
//     public Payload<?> getPayload() {
//         return payload;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/utils/NetworkUtil.java
// public class NetworkUtil {
// 
// 
//     // My favourite number. We need hardcoded port because we cannot broadcast over all ports
//     public static final int BASE_PORT = 52100;
// 
//     /**
//      * Checks to see if a specific port is available.
//      *
//      * @param port the port to check for availability
//      */
//     public static boolean available(int port) {
//         ServerSocket ss = null;
//         DatagramSocket ds = null;
//         try {
//             ss = new ServerSocket(port);
//             ss.setReuseAddress(true);
//             ds = new DatagramSocket(port);
//             ds.setReuseAddress(true);
//             return true;
//         } catch (IOException e) {
//         } finally {
//             if (ds != null) {
//                 ds.close();
//             }
// 
//             if (ss != null) {
//                 try {
//                     ss.close();
//                 } catch (IOException e) {
//                 /* should not be thrown */
//                 }
//             }
//         }
// 
//         return false;
//     }
// 
// 
//     public static long getIdFromIpAddress(String ipAddr) {
//         int[] ip = new int[4];
//         String[] parts = ipAddr.split("\\.");
// 
//         for (int i = 0; i < 4; i++) {
//             ip[i] = Integer.parseInt(parts[i]);
//         }
// 
//         long ipNumbers = 0;
//         for (int i = 0; i < 4; i++) {
//             ipNumbers += ip[i] << (24 - (8 * i));
//         }
// 
//         return ipNumbers;
//     }
// }


import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.NotificationCompat;
import android.text.format.Formatter;
import android.util.Log;
import java.util.HashMap;
import dev.jokr.localnet.discovery.models.DiscoveryReply;
import dev.jokr.localnet.models.ConnectedClients;
import dev.jokr.localnet.models.Payload;
import dev.jokr.localnet.models.RegisterMessage;
import dev.jokr.localnet.models.SessionMessage;
import dev.jokr.localnet.utils.NetworkUtil;
            e.printStackTrace();
        }
    }

    private void sendSessionStartMessage() {
        SessionMessage message = new SessionMessage(null, SessionMessage.START);
        for (RegisterMessage client : registeredClients.values()) {
            Thread t = new Thread(new SendHandler(message, client.getIp(), client.getPort()));
            t.start();
        }
    }


    private void runServiceInForeground() {
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("LocalNet Session")
                .setContentText("Session is currently running")
                .setSmallIcon(R.drawable.ic_play_circle_filled_black_24dp)
                .build();
        startForeground(NOTIFICATION_ID, notification);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onInitializedSocket(int port) {
// Path: localnet/src/main/java/dev/jokr/localnet/discovery/models/DiscoveryReply.java
// public class DiscoveryReply implements Serializable {
// 
//     private String ip;
//     private int port;
// 
//     public DiscoveryReply(String ip, int port) {
//         this.ip = ip;
//         this.port = port;
//     }
// 
//     public String getIp() {
//         return ip;
//     }
// 
//     public int getPort() {
//         return port;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/ConnectedClients.java
// public class ConnectedClients {
// 
//     private HashMap<Long, RegisterMessage> registeredClients;
// 
//     public ConnectedClients(HashMap<Long, RegisterMessage> registeredClients) {
//         this.registeredClients = registeredClients;
//     }
// 
//     public Payload<?> getPayload(int clientId) {
//         if (registeredClients.containsKey(clientId))
//             return registeredClients.get(clientId).getPayload();
//         else
//             return null;
//     }
// 
//     public Set<Long> getAllClientsIds() {
//         return registeredClients.keySet();
//     }
// 
//     public int getClientsSize() {
//         return registeredClients.size();
//     }
// 
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/Payload.java
// public class Payload<T> implements Serializable {
// 
//     private T payload;
// 
//     public Payload(T payload) {
//         this.payload = payload;
//     }
// 
//     public T getPayload() {
//         return payload;
//     }
// 
// 
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/RegisterMessage.java
// public class RegisterMessage implements Serializable {
// 
//     private Payload<?> payload;
//     private String ip;
//     private int port;
// 
//     public RegisterMessage(Payload<?> payload, String ip, int port) {
//         this.payload = payload;
//         this.ip = ip;
//         this.port = port;
//     }
// 
//     public String getIp() {
//         return ip;
//     }
// 
//     public int getPort() {
//         return port;
//     }
// 
//     public Payload<?> getPayload() {
//         return payload;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/models/SessionMessage.java
// public class SessionMessage implements Serializable {
// 
//     public static final int NONE = 0;
//     public static final int START = 1;
//     public static final int END = 2;
// 
//     private Payload<?> payload;
//     private int signal;
// 
// 
//     public SessionMessage(Payload<?> payload) {
//         this.payload = payload;
//         this.signal = NONE;
//     }
// 
//     public SessionMessage(Payload<?> payload, int signal) {
//         this.payload = payload;
//         this.signal = signal;
//     }
// 
//     public int getSignal() {
//         return signal;
//     }
// 
//     public Payload<?> getPayload() {
//         return payload;
//     }
// }
// 
// Path: localnet/src/main/java/dev/jokr/localnet/utils/NetworkUtil.java
// public class NetworkUtil {
// 
// 
//     // My favourite number. We need hardcoded port because we cannot broadcast over all ports
//     public static final int BASE_PORT = 52100;
// 
//     /**
//      * Checks to see if a specific port is available.
//      *
//      * @param port the port to check for availability
//      */
//     public static boolean available(int port) {
//         ServerSocket ss = null;
//         DatagramSocket ds = null;
//         try {
//             ss = new ServerSocket(port);
//             ss.setReuseAddress(true);
//             ds = new DatagramSocket(port);
//             ds.setReuseAddress(true);
//             return true;
//         } catch (IOException e) {
//         } finally {
//             if (ds != null) {
//                 ds.close();
//             }
// 
//             if (ss != null) {
//                 try {
//                     ss.close();
//                 } catch (IOException e) {
//                 /* should not be thrown */
//                 }
//             }
//         }
// 
//         return false;
//     }
// 
// 
//     public static long getIdFromIpAddress(String ipAddr) {
//         int[] ip = new int[4];
//         String[] parts = ipAddr.split("\\.");
// 
//         for (int i = 0; i < 4; i++) {
//             ip[i] = Integer.parseInt(parts[i]);
//         }
// 
//         long ipNumbers = 0;
//         for (int i = 0; i < 4; i++) {
//             ipNumbers += ip[i] << (24 - (8 * i));
//         }
// 
//         return ipNumbers;
//     }
// }


// Path: localnet/src/main/java/dev/jokr/localnet/ServerService.java
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.NotificationCompat;
import android.text.format.Formatter;
import android.util.Log;
import java.util.HashMap;
import dev.jokr.localnet.discovery.models.DiscoveryReply;
import dev.jokr.localnet.models.ConnectedClients;
import dev.jokr.localnet.models.Payload;
import dev.jokr.localnet.models.RegisterMessage;
import dev.jokr.localnet.models.SessionMessage;
import dev.jokr.localnet.utils.NetworkUtil;

            e.printStackTrace();
        }
    }

    private void sendSessionStartMessage() {
        SessionMessage message = new SessionMessage(null, SessionMessage.START);
        for (RegisterMessage client : registeredClients.values()) {
            Thread t = new Thread(new SendHandler(message, client.getIp(), client.getPort()));
            t.start();
        }
    }


    private void runServiceInForeground() {
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("LocalNet Session")
                .setContentText("Session is currently running")
                .setSmallIcon(R.drawable.ic_play_circle_filled_black_24dp)
                .build();
        startForeground(NOTIFICATION_ID, notification);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onInitializedSocket(int port) {
        discoverySocketThread = new Thread(new DiscoverySocketThread(new DiscoveryReply(getLocalIp(), port)));