// Path: dragonite-sdk/src/main/java/com/vecsight/dragonite/sdk/misc/DragoniteGlobalConstants.java
// public final class DragoniteGlobalConstants {
// 
//     public static final String LIBRARY_VERSION = DragoniteBuildConfig.VERSION;
// 
//     public static final byte PROTOCOL_VERSION = 2;
// 
//     public static final int MIN_SEND_WINDOW_SIZE = 20;
// 
//     public static final int ACK_INTERVAL_MS = 10;
// 
//     public static final int MAX_FAST_RESEND_COUNT = 3;
// 
//     public static final int MAX_SLOW_RESEND_MULT = 4;
// 
//     public static final int INIT_RTT_MS = 200, RTT_MAX_VARIATION_MS = 200, RTT_UPDATE_INTERVAL_MS = 100, RTT_RESEND_CORRECTION_INTERVAL_MS = 2000;
// 
//     public static final int DEV_RTT_MULT = 4;
// 
//     public static final float RTT_RESENDED_REFRESH_MAX_MULT = 1.5f;
// 
//     public static final int MIN_CLOSE_WAIT_MS = 100, CLOSE_WAIT_RTT_MULT = 4;
// 
//     public static final int WEB_PANEL_PORT = 8000;
// 
// }
// 
// Path: dragonite-sdk/src/main/java/com/vecsight/dragonite/sdk/socket/DragoniteSocketStatistics.java
// public class DragoniteSocketStatistics {
// 
//     private final SocketAddress remoteAddress;
// 
//     private final String description;
// 
//     private final long sendLength, sendRawLength, readLength, receiveRawLength, estimatedRTT, devRTT;
// 
//     private final long sendCount, resendCount, receiveCount, dupCount;
// 
//     public DragoniteSocketStatistics(final SocketAddress remoteAddress, final String description, final long sendLength, final long sendRawLength, final long readLength, final long receiveRawLength, final long estimatedRTT, final long devRTT, final long sendCount, final long resendCount, final long receiveCount, final long dupCount) {
//         this.remoteAddress = remoteAddress;
//         this.description = description;
//         this.sendLength = sendLength;
//         this.sendRawLength = sendRawLength;
//         this.readLength = readLength;
//         this.receiveRawLength = receiveRawLength;
//         this.estimatedRTT = estimatedRTT;
//         this.devRTT = devRTT;
//         this.sendCount = sendCount;
//         this.resendCount = resendCount;
//         this.receiveCount = receiveCount;
//         this.dupCount = dupCount;
//     }
// 
//     public long getSendLength() {
//         return sendLength;
//     }
// 
//     public long getSendRawLength() {
//         return sendRawLength;
//     }
// 
//     public long getReadLength() {
//         return readLength;
//     }
// 
//     public long getReceiveRawLength() {
//         return receiveRawLength;
//     }
// 
//     public long getEstimatedRTT() {
//         return estimatedRTT;
//     }
// 
//     public long getDevRTT() {
//         return devRTT;
//     }
// 
//     public long getSendCount() {
//         return sendCount;
//     }
// 
//     public long getResendCount() {
//         return resendCount;
//     }
// 
//     public long getReceiveCount() {
//         return receiveCount;
//     }
// 
//     public long getDupCount() {
//         return dupCount;
//     }
// 
//     public SocketAddress getRemoteAddress() {
//         return remoteAddress;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }


import com.sun.net.httpserver.HttpServer;
import com.vecsight.dragonite.sdk.misc.DragoniteGlobalConstants;
import com.vecsight.dragonite.sdk.socket.DragoniteSocketStatistics;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.sdk.web;



/*

sample:
{
  "title": "Dragonite Developer Web Interface",
  "version": "0.2.0",
  "connections": [
    {
      "remote": "123.123.123.123:54321",
      "description": "someEvilConnection",
      "rtt": 90,
      "devrtt": 5,
      "send": 10240,
      "sendraw": 12680,
      "sendpkt": 400,
      "resend": 60,
      "recv": 204800,
      "recvraw": 219400,
      "recvcount": 3800,
      "dup": 280
    }
  ]
}

 */

public class DevConsoleWebServer {

    private static final String WEB_TITLE = "Dragonite Developer Web Interface";

    private static final Charset CHARSET = StandardCharsets.UTF_8;

    private static final int SHUTDOWN_SEC = 2;

    private final HttpServer httpServer;

    private final StatisticsProvider statisticsProvider;

    public DevConsoleWebServer(final InetSocketAddress bindAddress, final StatisticsProvider provider) throws IOException {
        this.statisticsProvider = provider;

        httpServer = HttpServer.create(bindAddress, 0);
        httpServer.createContext("/statistics", httpExchange -> {
            final byte[] jsonBytes = getJSON(statisticsProvider.getLatest()).getBytes(CHARSET);
            httpExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
            httpExchange.sendResponseHeaders(200, jsonBytes.length);
            httpExchange.getResponseBody().write(jsonBytes);
            httpExchange.close();
        });

        httpServer.start();
    }

// Path: dragonite-sdk/src/main/java/com/vecsight/dragonite/sdk/misc/DragoniteGlobalConstants.java
// public final class DragoniteGlobalConstants {
// 
//     public static final String LIBRARY_VERSION = DragoniteBuildConfig.VERSION;
// 
//     public static final byte PROTOCOL_VERSION = 2;
// 
//     public static final int MIN_SEND_WINDOW_SIZE = 20;
// 
//     public static final int ACK_INTERVAL_MS = 10;
// 
//     public static final int MAX_FAST_RESEND_COUNT = 3;
// 
//     public static final int MAX_SLOW_RESEND_MULT = 4;
// 
//     public static final int INIT_RTT_MS = 200, RTT_MAX_VARIATION_MS = 200, RTT_UPDATE_INTERVAL_MS = 100, RTT_RESEND_CORRECTION_INTERVAL_MS = 2000;
// 
//     public static final int DEV_RTT_MULT = 4;
// 
//     public static final float RTT_RESENDED_REFRESH_MAX_MULT = 1.5f;
// 
//     public static final int MIN_CLOSE_WAIT_MS = 100, CLOSE_WAIT_RTT_MULT = 4;
// 
//     public static final int WEB_PANEL_PORT = 8000;
// 
// }
// 
// Path: dragonite-sdk/src/main/java/com/vecsight/dragonite/sdk/socket/DragoniteSocketStatistics.java
// public class DragoniteSocketStatistics {
// 
//     private final SocketAddress remoteAddress;
// 
//     private final String description;
// 
//     private final long sendLength, sendRawLength, readLength, receiveRawLength, estimatedRTT, devRTT;
// 
//     private final long sendCount, resendCount, receiveCount, dupCount;
// 
//     public DragoniteSocketStatistics(final SocketAddress remoteAddress, final String description, final long sendLength, final long sendRawLength, final long readLength, final long receiveRawLength, final long estimatedRTT, final long devRTT, final long sendCount, final long resendCount, final long receiveCount, final long dupCount) {
//         this.remoteAddress = remoteAddress;
//         this.description = description;
//         this.sendLength = sendLength;
//         this.sendRawLength = sendRawLength;
//         this.readLength = readLength;
//         this.receiveRawLength = receiveRawLength;
//         this.estimatedRTT = estimatedRTT;
//         this.devRTT = devRTT;
//         this.sendCount = sendCount;
//         this.resendCount = resendCount;
//         this.receiveCount = receiveCount;
//         this.dupCount = dupCount;
//     }
// 
//     public long getSendLength() {
//         return sendLength;
//     }
// 
//     public long getSendRawLength() {
//         return sendRawLength;
//     }
// 
//     public long getReadLength() {
//         return readLength;
//     }
// 
//     public long getReceiveRawLength() {
//         return receiveRawLength;
//     }
// 
//     public long getEstimatedRTT() {
//         return estimatedRTT;
//     }
// 
//     public long getDevRTT() {
//         return devRTT;
//     }
// 
//     public long getSendCount() {
//         return sendCount;
//     }
// 
//     public long getResendCount() {
//         return resendCount;
//     }
// 
//     public long getReceiveCount() {
//         return receiveCount;
//     }
// 
//     public long getDupCount() {
//         return dupCount;
//     }
// 
//     public SocketAddress getRemoteAddress() {
//         return remoteAddress;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }


// Path: dragonite-sdk/src/main/java/com/vecsight/dragonite/sdk/web/DevConsoleWebServer.java
import com.sun.net.httpserver.HttpServer;
import com.vecsight.dragonite.sdk.misc.DragoniteGlobalConstants;
import com.vecsight.dragonite.sdk.socket.DragoniteSocketStatistics;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.sdk.web;



/*

sample:
{
  "title": "Dragonite Developer Web Interface",
  "version": "0.2.0",
  "connections": [
    {
      "remote": "123.123.123.123:54321",
      "description": "someEvilConnection",
      "rtt": 90,
      "devrtt": 5,
      "send": 10240,
      "sendraw": 12680,
      "sendpkt": 400,
      "resend": 60,
      "recv": 204800,
      "recvraw": 219400,
      "recvcount": 3800,
      "dup": 280
    }
  ]
}

 */

public class DevConsoleWebServer {

    private static final String WEB_TITLE = "Dragonite Developer Web Interface";

    private static final Charset CHARSET = StandardCharsets.UTF_8;

    private static final int SHUTDOWN_SEC = 2;

    private final HttpServer httpServer;

    private final StatisticsProvider statisticsProvider;

    public DevConsoleWebServer(final InetSocketAddress bindAddress, final StatisticsProvider provider) throws IOException {
        this.statisticsProvider = provider;

        httpServer = HttpServer.create(bindAddress, 0);
        httpServer.createContext("/statistics", httpExchange -> {
            final byte[] jsonBytes = getJSON(statisticsProvider.getLatest()).getBytes(CHARSET);
            httpExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
            httpExchange.sendResponseHeaders(200, jsonBytes.length);
            httpExchange.getResponseBody().write(jsonBytes);
            httpExchange.close();
        });

        httpServer.start();
    }

    private String getJSON(final List<DragoniteSocketStatistics> statisticsList) {