package cx.cad.nfsn.net;

import com.squareup.okhttp.OkHttpClient;
import cx.cad.nfsn.API;
import org.apache.commons.io.IOUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;

public class APIExecutor {

    private static final Logger LOGGER = Logger.getLogger(APIExecutor.class.toString());

    public static APIResponse executeRequest(APIRequest request) {
        try {
            return executeRequest(request, getConnectionForPath(request.getPath()));
        } catch(MalformedURLException e){
            return new APIResponse(exceptionAsJson(e));
        }
    }

    public static HttpURLConnection getConnectionForPath(String path) throws MalformedURLException {
        URL url = buildRequestUrl(path);
        OkHttpClient client = new OkHttpClient();
        // Ignore invalid SSL endpoints.
        client.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });
        return client.open(url);
    }

    public static APIResponse executeRequest(APIRequest request, HttpURLConnection connection){
        InputStream in = null;
        try {
            connection.setRequestMethod(request.getMethod());
            connection.addRequestProperty(APIRequest.AUTH_HEADER, request.getAuthHeaderValue());

            LOGGER.info(String.format("HTTP %s %s with auth %s",
                    connection.getURL(),
                    connection.getRequestMethod(),
                    connection.getRequestProperty(APIRequest.AUTH_HEADER)));

            // Read the response.
            in = connection.getInputStream();
            String jsonResponse = IOUtils.toString(in, "UTF-8");
            return new APIResponse(jsonResponse);
        } catch (Throwable e) {
            return new APIResponse(exceptionAsJson(e), APIResponse.FAILURE);
        } finally {
            if (in != null) try {
                in.close();
            } catch (IOException e) {
                LOGGER.warning("Encountered " + e + " while closing the request input stream.");
            }
            if (connection != null)
                connection.disconnect();

        }
    }

    public static URL buildRequestUrl(String path) throws MalformedURLException {
        StringBuilder url = new StringBuilder();
        url.append(API.PROTOCOL).append("://").append(API.DOMAIN);
        url.append(path);
        return new URL(url.toString());
    }

    public static String exceptionAsJson(Throwable e) {
        return "{\"error\": \"" + e.toString() + "\"}";
    }
}

@@ -679,16 +679,17 @@
  %7D catch
+ 
 (Malform
@@ -705,16 +705,17 @@
 ption e)
+ 
 %7B%0A      
@@ -1354,16 +1354,17 @@
 nection)
+ 
 %7B%0A      
@@ -1601,16 +1601,18 @@
 format(%22
+%3E 
 HTTP %25s 
@@ -1960,77 +1960,584 @@
     
-return new APIResponse(jsonResponse);%0A        %7D catch (Throwable e) %7B
+LOGGER.info(String.format(%22%3C %25d %25s%22, connection.getResponseCode(), jsonResponse));%0A            return new APIResponse(jsonResponse);%0A        %7D catch (Throwable e) %7B%0A            try %7B%0A                LOGGER.info(String.format(%22%3C %25d %25s%22, connection.getResponseCode(), connection.getResponseMessage()));%0A                LOGGER.info(String.format(%22%3C %25s%22, IOUtils.toString(connection.getErrorStream(), %22UTF-8%22)));%0A%0A            %7D catch (IOException e1) %7B%0A                e1.printStackTrace();  //To change body of catch statement use File %7C Settings %7C File Templates.%0A            %7D%0A
 %0A   

add more logging to executor