package info.knacki.prometheusandroidexporter;

import android.content.Context;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HttpService {
    public final static Logger gLogger = Logger.getLogger(HttpService.class.getName());
    public static final short PORT = 8080;
    private static final HttpService gService = new HttpService();
    private HttpServer fServer = null;

    public static void Register(Context ctx) throws IOException {
        if (gService.fServer == null) {
            gService.fServer = HttpServer.create(new InetSocketAddress(PORT), 0);
            gService.fServer.setExecutor(Executors.newCachedThreadPool());
            gService.fServer.createContext("/", new HttpHandler() {
                @Override
                public void handle(HttpExchange httpExchange) {
                    try {
                        gService.ServeRoot(httpExchange);
                    }
                    catch (IOException e) {
                        gLogger.log(Level.SEVERE, "Cannot serve url /", e);
                    }
                }
            });
            gService.fServer.createContext("/metrics", new HttpHandler() {
                @Override
                public void handle(HttpExchange httpExchange) {
                    try {
                        gService.ServeMetrics(httpExchange);
                    }
                    catch (IOException e) {
                        gLogger.log(Level.SEVERE, "Cannot serve url /", e);
                    }
                }
            });
            gService.fServer.start();
        }
    }

    private void SendResponse(HttpExchange exh, int code, String contentType, String response) throws IOException {
        exh.sendResponseHeaders(code, response.length());
        if (contentType != null)
            exh.getResponseHeaders().add("Content-Type", contentType +"; charset=" +Charset.defaultCharset().displayName());
        // FIXME cache control
        OutputStream os = exh.getResponseBody();
        os.write(response.getBytes());
        os.flush();
        os.close();
    }

    private boolean FilterRequests(HttpExchange httpExchange) throws IOException {
        if (httpExchange.getRequestMethod().equals("GET"))
            return false;
        SendResponse(httpExchange, 405, null, "Method Not Allowed");
        return true;
    }

    private void ServeRoot(HttpExchange httpExchange) throws IOException {
        if (FilterRequests(httpExchange))
            return;
        String os = "<!DOCTYPE html5>\n" +
                "<html><body>\n" +
                "<a href='/metrics'>/metrics</a>\n" +
                "</body></html>";
        SendResponse(httpExchange, 200, "text/html", os);
    }

    private void ServeMetrics(HttpExchange httpExchange) throws IOException {
        if (FilterRequests(httpExchange))
            return;
        StringBuilder os = new StringBuilder();
        for (CollectorValue i : CollectorManager.GetInstance()) {
            os.append("# HELP ").append(i.fName).append(" ").append(i.fHelp).append("\n");
            os.append("# TYPE ").append(i.fName).append(" ").append(i.fType.fName).append("\n");
            os.append(i.fName).append(" ").append(i.toString()).append("\n");
        }
        SendResponse(httpExchange, 200, "text/plain", os.toString());
    }
}
