/*
 *******************************************************************************
 * Copyright (c) 2018 Contributors to the Eclipse Foundation
 * 
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
*/

package org.eclipse.openk.core.communication;


import org.apache.commons.httpclient.HostConfiguration;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.eclipse.openk.core.common.Globals;
import org.eclipse.openk.core.controller.BackendConfig;
import org.eclipse.openk.core.exceptions.HttpStatusException;

import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class RestServiceWrapper {
    public static class HttpHeader {
        private String attribute;
        private String value;

        public HttpHeader(String attribute, String value) {
            this.attribute = attribute;
            this.value = value;
        }

        public String getAttribute() {
            return attribute;
        }

        public void setAttribute(String attribute) {
            this.attribute = attribute;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    private static final Logger LOGGER = Logger.getLogger(RestServiceWrapper.class.getName());
    private boolean useHttps;

    public enum HttpMethod {GET, POST, PUT, DELETE}

    public RestServiceWrapper(boolean https) {
        this.useHttps = https;
    }

    public static HttpHeader createHeader(String attribute, String value) {
        return new HttpHeader(attribute, value);
    }

    public String performGetRequest(String restFunctionWithParams) throws HttpStatusException {
        LOGGER.debug("CompleteUrl: " + restFunctionWithParams);
        // create HTTP Client
        CloseableHttpClient httpClient = createHttpsClient();

        // create new Request with given URL
        HttpGet getRequest = new HttpGet(restFunctionWithParams);
        getRequest.addHeader("accept", Globals.HEADER_JSON_UTF8);

        HttpResponse response;
        // Execute request an catch response
        try {
            response = httpClient.execute(getRequest);

        } catch (IOException e) {
            String errtext = "Get communication to <" + restFunctionWithParams + "> failed.";
            LOGGER.warn(errtext, e);
            throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE);
        }

        return createJson(response);
    }

    public String performPostRequest(String restFunctionWithParams, String data) throws HttpStatusException {

        // create HTTP Client
        CloseableHttpClient httpClient = createHttpsClient();

        // create new Post Request with given URL
        HttpPost postRequest = new HttpPost(restFunctionWithParams);

        // add additional header to getRequest which accepts application/JSON data
        postRequest.addHeader("accept", Globals.HEADER_JSON_UTF8);
        postRequest.addHeader("Content-Type", Globals.HEADER_JSON_UTF8);

        postRequest.setEntity(new StringEntity(data, StandardCharsets.UTF_8));

        HttpResponse response;
        // Execute request an catch response
        try {
            response = httpClient.execute(postRequest);
        } catch (IOException e) {
            String errtext = "Post communication to <" + restFunctionWithParams + "> failed!";
            LOGGER.warn(errtext, e);
            throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE);
        }
        return createJson(response);
    }

    public Response performHttpRequest(HttpMethod method, String restFunctionWithParams,
                                       List<HttpHeader> headerList, String data) throws HttpStatusException {

        // create HTTP Client
        try (CloseableHttpClient httpClient = createHttpsClient() ) {

            HttpRequestBase request = createRequest(method, restFunctionWithParams, data);
            for (HttpHeader header : headerList) {
                request.addHeader(header.attribute, header.value);
            }

            HttpResponse response;
            // Execute request an catch response
            response = httpClient.execute(request);


            String ent = createJson(response);

            Response.ResponseBuilder rb = Response.status(response.getStatusLine().getStatusCode());
            if (ent != null) {
                rb.entity(ent);
            }
            return rb.build();
        } catch (IOException e) {
            String errtext = "Communication to <" + restFunctionWithParams + "> failed...";
            LOGGER.warn(errtext, e);
            throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE);
        }
    }

    private HttpRequestBase createRequest(HttpMethod method, String restFunctionWithParams, String data) throws HttpStatusException {
        HttpRequestBase ret;
        switch (method) {
            case GET:
                ret = new HttpGet(restFunctionWithParams);
                break;
            case POST:
                ret = setPayload(new HttpPost(restFunctionWithParams), data);
                break;
            case PUT:
                ret = setPayload(new HttpPut(restFunctionWithParams), data);
                break;
            case DELETE:
                ret = new HttpDelete(restFunctionWithParams);
                break;
            default:
                throw new HttpStatusException(HttpStatus.SC_METHOD_NOT_ALLOWED);
        }
        return ret;
    }

    private HttpRequestBase setPayload(HttpEntityEnclosingRequestBase req, String data) {
        req.setEntity(new StringEntity(data, StandardCharsets.UTF_8));
        return req;
    }


    private CloseableHttpClient createHttpsClient() throws HttpStatusException {
        if (useHttps) {
            try {
                SSLContextBuilder builder = new SSLContextBuilder();
                builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());

                String proxyHost = BackendConfig.getInstance().getProxyHost();
                int proxyPort = BackendConfig.getInstance().getProxyPort();
                if (proxyHost != null && !proxyHost.isEmpty()){
                    return HttpClients.custom().setSSLSocketFactory(sslsf).setProxy(new HttpHost(proxyHost, proxyPort)).build();
                }

                return HttpClients.custom().setSSLSocketFactory(sslsf).build();
            } catch (Exception e) {
                LOGGER.error(e);
                throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            }
        } else {
            return HttpClientBuilder.create().build();
        }
    }

    private String createJson(HttpResponse response) throws HttpStatusException {
        String retJson;
        try {
            retJson = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            LOGGER.error(e);
            throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR);
        }

        return retJson;
    }

}
