
package com.ppm.integration.agilesdk.connector.jira.rest.util;

import com.ppm.integration.agilesdk.connector.jira.rest.util.exception.RestRequestException;
import org.apache.commons.lang.StringUtils;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;

import javax.ws.rs.core.MediaType;
import java.io.UnsupportedEncodingException;
import java.net.*;

public class JiraRestWrapper {

    private RestClient restClient;
    private IRestConfig config;

    public JiraRestWrapper(IRestConfig config) {
        this.config = config;
        restClient = createRestClient(config);
    }

    private RestClient createRestClient(IRestConfig config) {
        restClient = new RestClient(config.getClientConfig());
        return restClient;
    }

    private Resource getJIRAResource(String urlAdd) {
        Resource resource;
        try {
            URL url = new URL(urlAdd);
            String urlPath = url.getHost();
            if (url.getPort() > 0) {
                urlPath = urlPath + ":" + url.getPort();
            }
            URI uri = null;
            try {
                uri = new URI(url.getProtocol(), urlPath, url.getPath(), url.getQuery() == null ? null : URLDecoder.decode(url.getQuery(), "UTF-8"), null);
            } catch (UnsupportedEncodingException e) {
                // This will never happen.
                throw new RuntimeException("Impossible encoding error occurred", e);
            }
            resource = restClient.resource(uri).contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON).header("Authorization", config.getBasicAuthorizationToken());
        } catch (MalformedURLException e) {
            throw new RestRequestException( // is a malformed URL
                    400, String.format("%s is a malformed URL", urlAdd));
        } catch (URISyntaxException e) {
            throw new RestRequestException(400, String.format("%s is a malformed URL", urlAdd));
        }
        return resource;
    }

    public ClientResponse sendGet(String uri) {
        Resource resource = this.getJIRAResource(uri);
        ClientResponse response = resource.get();

        checkResponseStatus(200, response, uri, "GET", null);

        return response;
    }

    private void checkResponseStatus(int expectedHttpStatusCode, ClientResponse response, String uri, String verb, String payload) {

        if (response.getStatusCode() != expectedHttpStatusCode) {
            StringBuilder errorMessage = new StringBuilder(String.format("## Unexpected HTTP response status code %s for %s uri %s, expected %s", response.getStatusCode(), verb,  uri, expectedHttpStatusCode));
            if (payload != null) {
                errorMessage.append(System.lineSeparator()).append(System.lineSeparator()).append("# Sent Payload:").append(System.lineSeparator()).append(payload);
            }
            String responseStr = null;
            try {
                responseStr = response.getEntity(String.class);
            } catch (Exception e) {
                // we don't do anything if we cannot get the response.
            }
            if (!StringUtils.isBlank(responseStr)) {
                errorMessage.append(System.lineSeparator()).append(System.lineSeparator()).append("# Received Response:").append(System.lineSeparator()).append(responseStr);
            }

            throw new RestRequestException(response.getStatusCode(), errorMessage.toString());
        }

    }

    public ClientResponse sendPost(String uri, String jsonPayload, int expectedHttpStatusCode) {
        Resource resource = this.getJIRAResource(uri);
        ClientResponse response = resource.post(jsonPayload);

        checkResponseStatus(expectedHttpStatusCode, response, uri, "POST", jsonPayload);

        return response;
    }

    public ClientResponse sendPut(String uri, String jsonPayload, int expectedHttpStatusCode) {
        Resource resource = this.getJIRAResource(uri);
        ClientResponse response = resource.put(jsonPayload);

        checkResponseStatus(expectedHttpStatusCode, response, uri, "PUT", jsonPayload);

        return response;
    }
}

@@ -808,32 +808,245 @@
 tClient;%0A    %7D%0A%0A
+    /**%0A%0A     * @param includeContentTypeHeader if true, we'll include the JSon %22Content-Type%22 header. If false, we'll not include any Content-type header (to use when using GET or DELETE).%0A     * @return%0A     */%0A
     private Reso
@@ -1079,16 +1079,50 @@
 g urlAdd
+, boolean includeContentTypeHeader
 ) %7B%0A    
@@ -1799,69 +1799,8 @@
 uri)
-.contentType(MediaType.APPLICATION_JSON)%0A                    
 .acc
@@ -1889,24 +1889,150 @@
 onToken());%0A
+%0A            if (includeContentTypeHeader) %7B%0A                resource.contentType(MediaType.APPLICATION_JSON);%0A            %7D%0A%0A
         %7D ca
@@ -2475,32 +2475,39 @@
 JIRAResource(uri
+, false
 );%0A        Clien
@@ -4001,32 +4001,38 @@
 JIRAResource(uri
+, true
 );%0A        Clien
@@ -4291,32 +4291,32 @@
 tpStatusCode) %7B%0A
-
         Resource
@@ -4351,16 +4351,21 @@
 urce(uri
+,true
 );%0A     

Remove content-type header when doing HTTP GET to Jira Server (#40)