// Path: core/src/main/java/io/keen/client/java/KeenVersion.java
// public class KeenVersion {
// 
//     private static final String SDK_VERSION = "5.6.0";
// 
//     private KeenVersion() {
//     }
// 
//     public static String getSdkVersion() {
//         return SDK_VERSION;
//     }
// 
// }


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import io.keen.client.java.KeenUtils;
import io.keen.client.java.KeenVersion;
package io.keen.client.java.http;



/**
 * This class provides a default implementation of {@link HttpHandler} using
 * {@link java.net.HttpURLConnection}. To use a different HttpURLConnection implementation simply
 * override the {@link UrlConnectionHttpHandler#execute(Request)}} method.
 *
 * @author Kevin Litwack (kevin@kevinlitwack.com)
 * @since 2.0.0
 */
public class UrlConnectionHttpHandler implements HttpHandler {

    /**
     * Sends an HTTP request.
     *
     * @param request The {@link Request} to send.
     * @return A {@link Response} object describing the response from the server.
     * @throws IOException If there was an error during the connection.
     */
    @Override
    public Response execute(Request request) throws IOException {
        HttpURLConnection connection = openConnection(request);
        sendRequest(connection, request);
        return readResponse(connection);
    }

    ///// PROTECTED METHODS /////

    /**
     * Opens a connection based on the URL in the given request.
     *
     * Subclasses can override this method to use a different implementation of
     * {@link HttpURLConnection}.
     *
     * @param request The {@link Request}.
     * @return A new {@link HttpURLConnection}.
     * @throws IOException If there is an error opening the connection.
     */
    protected HttpURLConnection openConnection(Request request) throws IOException {
        HttpURLConnection result;
        if (request.proxy != null) {
            result = (HttpURLConnection) request.url.openConnection(request.proxy);
        } else {
            result = (HttpURLConnection) request.url.openConnection();
        }
        result.setConnectTimeout(request.connectTimeout);
        result.setReadTimeout(request.readTimeout);
        return result;
    }

    /**
     * Sends a request over a given connection.
     *
     * @param connection The connection over which to send the request.
     * @param request The request to send.
     * @throws IOException If there is an error sending the request.
     */
    protected void sendRequest(HttpURLConnection connection, Request request) throws IOException {
        // Set up the request.
        connection.setRequestMethod(request.method);
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("Authorization", request.authorization);

        // If a different HttpHandler is used, we won't get this header. We would need to refactor
        // to a delegation pattern to give the client code's HttpHandler a chance to process the
        // Request first, then attach our custom headers, which would likely be a breaking change.
// Path: core/src/main/java/io/keen/client/java/KeenVersion.java
// public class KeenVersion {
// 
//     private static final String SDK_VERSION = "5.6.0";
// 
//     private KeenVersion() {
//     }
// 
//     public static String getSdkVersion() {
//         return SDK_VERSION;
//     }
// 
// }


// Path: core/src/main/java/io/keen/client/java/http/UrlConnectionHttpHandler.java
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import io.keen.client.java.KeenUtils;
import io.keen.client.java.KeenVersion;

package io.keen.client.java.http;



/**
 * This class provides a default implementation of {@link HttpHandler} using
 * {@link java.net.HttpURLConnection}. To use a different HttpURLConnection implementation simply
 * override the {@link UrlConnectionHttpHandler#execute(Request)}} method.
 *
 * @author Kevin Litwack (kevin@kevinlitwack.com)
 * @since 2.0.0
 */
public class UrlConnectionHttpHandler implements HttpHandler {

    /**
     * Sends an HTTP request.
     *
     * @param request The {@link Request} to send.
     * @return A {@link Response} object describing the response from the server.
     * @throws IOException If there was an error during the connection.
     */
    @Override
    public Response execute(Request request) throws IOException {
        HttpURLConnection connection = openConnection(request);
        sendRequest(connection, request);
        return readResponse(connection);
    }

    ///// PROTECTED METHODS /////

    /**
     * Opens a connection based on the URL in the given request.
     *
     * Subclasses can override this method to use a different implementation of
     * {@link HttpURLConnection}.
     *
     * @param request The {@link Request}.
     * @return A new {@link HttpURLConnection}.
     * @throws IOException If there is an error opening the connection.
     */
    protected HttpURLConnection openConnection(Request request) throws IOException {
        HttpURLConnection result;
        if (request.proxy != null) {
            result = (HttpURLConnection) request.url.openConnection(request.proxy);
        } else {
            result = (HttpURLConnection) request.url.openConnection();
        }
        result.setConnectTimeout(request.connectTimeout);
        result.setReadTimeout(request.readTimeout);
        return result;
    }

    /**
     * Sends a request over a given connection.
     *
     * @param connection The connection over which to send the request.
     * @param request The request to send.
     * @throws IOException If there is an error sending the request.
     */
    protected void sendRequest(HttpURLConnection connection, Request request) throws IOException {
        // Set up the request.
        connection.setRequestMethod(request.method);
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("Authorization", request.authorization);

        // If a different HttpHandler is used, we won't get this header. We would need to refactor
        // to a delegation pattern to give the client code's HttpHandler a chance to process the
        // Request first, then attach our custom headers, which would likely be a breaking change.
        connection.setRequestProperty("Keen-Sdk", "java-" + KeenVersion.getSdkVersion());