/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.apache.ofbiz.base.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Send HTTP GET/POST requests.
 * The main problem with current implementation is that it does not handle connections release. You must rely on the SO to release them (timeout).
 *
 */
public class HttpClient {

    public static final String module = HttpClient.class.getName();

    private int hostVerification = SSLUtil.getHostCertNormalCheck();
    private int timeout = 30000;
    private boolean debug = false;
    private boolean lineFeed = true;
    private boolean trustAny = false;
    private boolean followRedirects = true;
    private boolean keepAlive = false;

    private String contentType = null;
    private String streamCharset = null;
    private String url = null;
    private String rawStream = null;
    private String clientCertAlias = null;
    private String basicAuthUsername = null;
    private String basicAuthPassword = null;

    private Map<String, Object> parameters = null;
    private Map<String, String> headers = null;

    private URL requestUrl = null;
    private URLConnection con = null;

    /** Creates an empty HttpClient object. */
    public HttpClient() {}

    /** Creates a new HttpClient object. */
    public HttpClient(URL url) {
        this.url = url.toExternalForm();
    }

    /** Creates a new HttpClient object. */
    public HttpClient(String url) {
        this.url = url;
    }

    /** Creates a new HttpClient object. */
    public HttpClient(String url, Map<String, Object> parameters) {
        this.url = url;
        this.parameters = parameters;
    }

    /** Creates a new HttpClient object. */
    public HttpClient(URL url, Map<String, Object> parameters) {
        this.url = url.toExternalForm();
        this.parameters = parameters;
    }

    /** Creates a new HttpClient object. */
    public HttpClient(String url, Map<String, Object> parameters, Map<String, String> headers) {
        this.url = url;
        this.parameters = parameters;
        this.headers = headers;
    }

    /** Creates a new HttpClient object. */
    public HttpClient(URL url, Map<String, Object> parameters, Map<String, String> headers) {
        this.url = url.toExternalForm();
        this.parameters = parameters;
        this.headers = headers;
    }

    /** When true overrides Debug.verboseOn() and forces debugging for this instance */
    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    /** Sets the timeout for waiting for the connection (default 30sec) */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /** Enables this request to follow redirect 3xx codes (default true) */
     public void followRedirects(boolean followRedirects) {
        this.followRedirects = followRedirects;
    }

    /** Turns on or off line feeds in the request. (default is on) */
    public void setLineFeed(boolean lineFeed) {
        this.lineFeed = lineFeed;
    }

    /** Set the raw stream for posts. */
    public void setRawStream(String stream) {
        this.rawStream = stream;
    }

    /** Set the URL for this request. */
    public void setUrl(URL url) {
        this.url = url.toExternalForm();
    }

    /** Set the URL for this request. */
    public void setUrl(String url) {
        this.url = url;
    }

    /** Set the parameters for this request. */
    public void setParameters(Map<String, Object> parameters) {
        this.parameters = parameters;
    }

    /** Set an individual parameter for this request. */
    public void setParameter(String name, String value) {
        if (parameters == null)
            parameters = new HashMap<String, Object>();
        parameters.put(name, value);
    }

    /** Set the headers for this request. */
    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    /** Set an individual header for this request. */
    public void setHeader(String name, String value) {
        if (headers == null)
            headers = new HashMap<String, String>();
        headers.put(name, value);
    }

    /** Return a Map of headers. */
    public Map<String, String> getHeaders() {
        return headers;
    }

    /** Return a Map of parameters. */
    public Map<String, Object> getParameters() {
        return parameters;
    }

    /** Return a string representing the requested URL. */
    public String getUrl() {
        return url;
    }

    /** Sets the content-type */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /** Returns the content type */
    public String getContentType() {
        return this.contentType;
    }
    
    /** Sets the scream charset */
    public void setStreamCharset(String streamCharset) {
        this.streamCharset = streamCharset;
    }
    
    /** Returns the stream charset */
    public String getStreamCharset() {
        return this.streamCharset;
    }

    /** Toggle keep-alive setting */
    public void setKeepAlive(boolean keepAlive) {
        this.keepAlive = keepAlive;
    }

    /** Return keep-alive setting */
    public boolean getKeepAlive() {
        return this.keepAlive;
    }

    /** Sets the client certificate alias (from the keystore) to use for this SSL connection. */
    public void setClientCertificateAlias(String alias) {
        this.clientCertAlias = alias;
    }

    /** Returns the alias of the client certificate to be used for this SSL connection. */
    public String getClientCertificateAlias() {
        return this.clientCertAlias;
    }

    /** Sets the server hostname verification level */
    public void setHostVerificationLevel(int level) {
        this.hostVerification = level;
    }

    /** Returns the current server hostname verification level */
    public int getHostVerificationLevel() {
        return this.hostVerification;
    }

    /** Allow untrusted server certificates */
    public void setAllowUntrusted(boolean trustAny) {
        this.trustAny = trustAny;
    }

    /** Do we trust any certificate */
    public boolean getAllowUntrusted() {
        return this.trustAny;
    }

    public void setBasicAuthInfo(String basicAuthUsername, String basicAuthPassword) {
        this.basicAuthUsername = basicAuthUsername;
        this.basicAuthPassword = basicAuthPassword;
    }

    /** Invoke HTTP request GET. */
    public String get() throws HttpClientException {
        return sendHttpRequest("get");
    }

    /** Invoke HTTP request GET. */
    public InputStream getStream() throws HttpClientException {
        return sendHttpRequestStream("get");
    }

    /** Invoke HTTP request POST. */
    public String post() throws HttpClientException {
        return sendHttpRequest("post");
    }

    /** Invoke HTTP request POST and pass raw stream. */
    public String post(String stream) throws HttpClientException {
        this.rawStream = stream;
        return sendHttpRequest("post");
    }

    /** Invoke HTTP request POST. */
    public InputStream postStream() throws HttpClientException {
        return sendHttpRequestStream("post");
    }

    /** Returns the value of the specified named response header field. */
    public String getResponseHeader(String header) throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getHeaderField(header);
    }

    /** Returns the key for the nth response header field. */
    public String getResponseHeaderFieldKey(int n) throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getHeaderFieldKey(n);
    }

    /** Returns the value for the nth response header field. It returns null of there are fewer then n fields. */
    public String getResponseHeaderField(int n) throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getHeaderField(n);
    }

    /** Returns the content of the response. */
    public Object getResponseContent() throws java.io.IOException, HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getContent();
    }

    /** Returns the content-type of the response. */
    public String getResponseContentType() throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getContentType();
    }

    /** Returns the content length of the response */
    public int getResponseContentLength() throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getContentLength();
    }

    /** Returns the content encoding of the response. */
    public String getResponseContentEncoding() throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        return con.getContentEncoding();
    }

    public int getResponseCode() throws HttpClientException {
        if (con == null) {
            throw new HttpClientException("Connection not yet established");
        }
        if (!(con instanceof HttpURLConnection)) {
            throw new HttpClientException("Connection is not HTTP; no response code");
        }

        try {
            return ((HttpURLConnection) con).getResponseCode();
        } catch (IOException e) {
            throw new HttpClientException(e.getMessage(), e);
        }
    }

    public String sendHttpRequest(String method) throws HttpClientException {
        InputStream in = sendHttpRequestStream(method);
        if (in == null) return null;

        StringBuilder buf = new StringBuilder();
        try {
            if (Debug.verboseOn() || debug) {
                try {
                    Debug.logInfo("ContentEncoding: " + con.getContentEncoding() + "; ContentType: " +
                            con.getContentType() + " or: " + URLConnection.guessContentTypeFromStream(in), module);
                } catch (IOException ioe) {
                    Debug.logWarning(ioe, "Caught exception printing content debugging information", module);
                }
            }

            String charset = null;
            String contentType = con.getContentType();
            if (contentType == null) {
                try {
                    contentType = URLConnection.guessContentTypeFromStream(in);
                } catch (IOException ioe) {
                    Debug.logWarning(ioe, "Problems guessing content type from steam", module);
                }
            }

            if (Debug.verboseOn() || debug) Debug.logVerbose("Content-Type: " + contentType, module);

            if (contentType != null) {
                contentType = contentType.toUpperCase();
                int charsetEqualsLoc = contentType.indexOf("=", contentType.indexOf("CHARSET"));
                int afterSemiColon = contentType.indexOf(";", charsetEqualsLoc);
                if (charsetEqualsLoc >= 0 && afterSemiColon >= 0) {
                    charset = contentType.substring(charsetEqualsLoc + 1, afterSemiColon);
                } else if (charsetEqualsLoc >= 0) {
                    charset = contentType.substring(charsetEqualsLoc + 1);
                }

                if (charset != null) charset = charset.trim().replaceAll("\"", "");
                if (Debug.verboseOn() || debug) Debug.logVerbose("Getting text from HttpClient with charset: " + charset, module);
            }

            BufferedReader post = new BufferedReader(charset == null ? new InputStreamReader(in) : new InputStreamReader(in, charset));
            String line = "";

            if (Debug.verboseOn() || debug) Debug.logVerbose("---- HttpClient Response Content ----", module);
            while ((line = post.readLine()) != null) {
                if (Debug.verboseOn() || debug) Debug.logVerbose("[HttpClient] : " + line, module);
                buf.append(line);
                if (lineFeed) {
                    buf.append("\n");
                }
            }
        } catch (Exception e) {
            throw new HttpClientException("Error processing input stream", e);
        }
        return buf.toString();
    }

    private InputStream sendHttpRequestStream(String method) throws HttpClientException {
        return sendHttpRequestStream(method, false);
    }

    private InputStream sendHttpRequestStream(String method, boolean overrideTrust) throws HttpClientException {
        // setup some SSL variables
        SSLUtil.loadJsseProperties(this.debug);

        String arguments = null;
        InputStream in = null;

        if (url == null) {
            throw new HttpClientException("Cannot process a null URL.");
        }

        if (rawStream != null) {
            arguments = rawStream;
        } else if (UtilValidate.isNotEmpty(parameters)) {
            arguments = UtilHttp.urlEncodeArgs(parameters, false);
        }

        // Append the arguments to the query string if GET.
        if (method.equalsIgnoreCase("get") && arguments != null) {
            if (url.contains("?")) {
                url = url + "&" + arguments;
            } else {
                url = url + "?" + arguments;
            }
        }

        // Create the URL and open the connection.
        try {
            requestUrl = new URL(url);
            if (overrideTrust) {
                con = URLConnector.openUntrustedConnection(requestUrl, timeout, clientCertAlias, hostVerification);
            } else {
                con = URLConnector.openConnection(requestUrl, timeout, clientCertAlias, hostVerification);
            }
            if (Debug.verboseOn() || debug) Debug.logVerbose("Connection opened to : " + requestUrl.toExternalForm(), module);

            if ((con instanceof HttpURLConnection)) {
                ((HttpURLConnection) con).setInstanceFollowRedirects(followRedirects);
                if (Debug.verboseOn() || debug) Debug.logVerbose("Connection is of type HttpURLConnection, more specifically: " + con.getClass().getName(), module);
            }

            // set the content type
            if (contentType != null) {
                con.setRequestProperty("Content-type", contentType);
            }

            // connection settings
            con.setDoOutput(true);
            con.setUseCaches(false);
            if (keepAlive) {
                con.setRequestProperty("Connection", "Keep-Alive");
            }

            if (method.equalsIgnoreCase("post")) {
                if (contentType == null) {
                    con.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
                }
                con.setDoInput(true);
            }

            // if there is basicAuth info set the request property for it
            if (basicAuthUsername != null) {
                String basicAuthString = "Basic " + Base64.base64Encode(basicAuthUsername + ":" + (basicAuthPassword == null ? "" : basicAuthPassword));
                con.setRequestProperty("Authorization", basicAuthString);
                if (Debug.verboseOn() || debug) Debug.logVerbose("Header - Authorization: " + basicAuthString, module);
            }

            if (UtilValidate.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry: headers.entrySet()) {
                    String headerName = entry.getKey();
                    String headerValue = entry.getValue();
                    con.setRequestProperty(headerName, headerValue);
                    if (Debug.verboseOn() || debug) Debug.logVerbose("Header - " + headerName + ": " + headerValue, module);
                }
            }

            if (method.equalsIgnoreCase("post")) {
                OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(), this.streamCharset != null ? this.streamCharset : "UTF-8");
                if (Debug.verboseOn() || debug) Debug.logVerbose("Opened output stream", module);

                if (arguments != null) {
                    out.write(arguments);
                    if (Debug.verboseOn() || debug) Debug.logVerbose("Wrote arguements (parameters) : " + arguments, module);
                }

                out.flush();
                out.close();
                if (Debug.verboseOn() || debug) Debug.logVerbose("Flushed and closed buffer", module);
            }

            if (Debug.verboseOn() || debug) {
                Map<String, List<String>> headerFields = con.getHeaderFields();
                Debug.logInfo("Header Fields : " + headerFields, module);
            }

            in = con.getInputStream();
        } catch (IOException ioe) {
            if ((trustAny && !overrideTrust) && (ioe.getCause() instanceof CertificateException)) {
                Debug.logWarning(ioe.getCause(), module);
                return sendHttpRequestStream(method, true);
            }
            throw new HttpClientException("IO Error processing request", ioe);
        } catch (Exception e) {
            throw new HttpClientException("Error processing request", e);
        }

        return in;
    }


    public static String getUrlContent(String url) throws HttpClientException {
        HttpClient client = new HttpClient(url);
        return client.get();
    }

    public static int checkHttpRequest(String url) throws HttpClientException {
        HttpClient client = new HttpClient(url);
        client.get();
        return client.getResponseCode();
    }
}
