import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;

public class PortalRestClient {
    private static final String DEFAULT_HOST = "https://agent-api-2.waratek.com";
    private static final String DEFAULT_ENDPOINT = "/api/2/agents/status";
    private static final String PORTAL_STATUS_METHOD = "PUT";
    private static final int DEFAULT_CONNECTION_TIMEOUT_MS = 20 * 1000; // 20 seconds
    private static final int DEFAULT_READ_TIMEOUT_MS = 50 * 1000; // 50 seconds
    private static final String TLS_V1_2 = "TLSv1.2";

    public static void main(String[] args) throws Exception {
        try {
            String host = DEFAULT_HOST;
            if (args != null && args.length > 0) {
                host = args[0];
            }
            doConnection(host + DEFAULT_ENDPOINT);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static void doConnection(String url) throws Exception {
        System.out.println("start doConnection to " + url);
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        customizeConnection(conn);
        forceTls12IfSupported(conn);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setRequestMethod(PORTAL_STATUS_METHOD);

        OutputStream connStream = conn.getOutputStream();
        connStream.write("hello".getBytes());
        connStream.close();
        conn.connect();

        System.out.println("response: " + conn.getResponseCode());

        conn.disconnect();
        System.out.println("end doConnection");
    }

    /**
     * Common settings for any connection made by the Agent to Portal
     */
    private static void customizeConnection(HttpURLConnection conn) {
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(false);
        conn.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT_MS);
        conn.setReadTimeout(DEFAULT_READ_TIMEOUT_MS);
    }

    private static void forceTls12IfSupported(HttpURLConnection conn) {
        if (!(conn instanceof HttpsURLConnection)) {
            return;
        }
        if (!isTls12Supported()) {
            System.out.println("Not trying to force " + TLS_V1_2);
            return;
        }
        if (doForceTls12IfSupported((HttpsURLConnection) conn)) {
            System.out.println("Forcing " + TLS_V1_2 + " was successful");
        } else {
            System.out.println("Forcing " + TLS_V1_2 + " has failed");
        }
    }

    public static boolean isTls12Supported() {
        try {
            SSLContext.getInstance(TLS_V1_2);
            return true;
        } catch (Exception ignore) {}

        return false;
    }

    private static boolean doForceTls12IfSupported(HttpsURLConnection secureConn) {
        try {
            SSLContext sslContext = SSLContext.getInstance(TLS_V1_2);
            sslContext.init(null, null, new SecureRandom());
            secureConn.setSSLSocketFactory(sslContext.getSocketFactory());
            return true;
        } catch (Exception tlsException) {
            tlsException.printStackTrace();
        }
        return false;
    }
}
