/*
 * 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.chemistry.opencmis.client.bindings.spi.http;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import org.apache.chemistry.opencmis.client.bindings.impl.CmisBindingsHelper;
import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
import org.apache.chemistry.opencmis.commons.spi.AuthenticationProvider;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpInetSocketAddress;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeLayeredSocketFactory;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

/**
 * A {@link HttpInvoker} that uses The Apache HTTP client.
 */
public class ApacheClientHttpInvoker extends AbstractApacheClientHttpInvoker {

    protected DefaultHttpClient createHttpClient(UrlBuilder url, BindingSession session) {
        // set params
        HttpParams params = createDefaultHttpParams(session);
        params.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);

        // set up scheme registry and connection manager
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
        registry.register(new Scheme("https", 443, getSSLSocketFactory(url, session)));

        // set up connection manager
        PoolingClientConnectionManager connManager = new PoolingClientConnectionManager(registry);

        // set max connection a
        String keepAliveStr = System.getProperty("http.keepAlive", "true");
        if ("true".equalsIgnoreCase(keepAliveStr)) {
            String maxConnStr = System.getProperty("http.maxConnections", "5");
            int maxConn = 5;
            try {
                maxConn = Integer.parseInt(maxConnStr);
            } catch (NumberFormatException nfe) {
                // ignore
            }
            connManager.setDefaultMaxPerRoute(maxConn);
            connManager.setMaxTotal(4 * maxConn);
        }

        // set up proxy
        ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(registry, null);

        // set up client
        DefaultHttpClient httpclient = new DefaultHttpClient(connManager, params);
        httpclient.setRoutePlanner(routePlanner);

        return httpclient;
    }

    /**
     * Builds a SSL Socket Factory for the Apache HTTP Client.
     */
    private SchemeLayeredSocketFactory getSSLSocketFactory(final UrlBuilder url, final BindingSession session) {
        // get authentication provider
        AuthenticationProvider authProvider = CmisBindingsHelper.getAuthenticationProvider(session);

        // check SSL Socket Factory
        final SSLSocketFactory sf = authProvider.getSSLSocketFactory();
        if (sf == null) {
            // no custom factory -> return default factory
            return org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory();
        }

        // check hostame verifier and use default if not set
        final HostnameVerifier hv = (authProvider.getHostnameVerifier() == null ? new BrowserCompatHostnameVerifier()
                : authProvider.getHostnameVerifier());

        if (hv instanceof X509HostnameVerifier) {
            return new org.apache.http.conn.ssl.SSLSocketFactory(sf, (X509HostnameVerifier) hv);
        }

        // build new socket factory
        return new SchemeLayeredSocketFactory() {

            public boolean isSecure(Socket sock) {
                return true;
            }

            public Socket createSocket(HttpParams params) throws IOException {
                return sf.createSocket();
            }

            public Socket connectSocket(final Socket socket, final InetSocketAddress remoteAddress,
                    final InetSocketAddress localAddress, final HttpParams params) throws IOException {

                Socket sock = (socket != null ? socket : createSocket(params));
                if (localAddress != null) {
                    sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
                    sock.bind(localAddress);
                }

                int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
                int soTimeout = HttpConnectionParams.getSoTimeout(params);

                try {
                    sock.setSoTimeout(soTimeout);
                    sock.connect(remoteAddress, connTimeout);
                } catch (SocketTimeoutException ex) {
                    closeSocket(sock);
                    throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out!");
                }

                String host;
                if (remoteAddress instanceof HttpInetSocketAddress) {
                    host = ((HttpInetSocketAddress) remoteAddress).getHttpHost().getHostName();
                } else {
                    host = remoteAddress.getHostName();
                }

                SSLSocket sslSocket;
                if (sock instanceof SSLSocket) {
                    sslSocket = (SSLSocket) sock;
                } else {
                    int port = remoteAddress.getPort();
                    sslSocket = (SSLSocket) sf.createSocket(sock, host, port, true);
                }
                verify(hv, host, sslSocket);

                return sslSocket;
            }

            public Socket createLayeredSocket(final Socket socket, final String host, final int port,
                    final HttpParams params) throws IOException {
                SSLSocket sslSocket = (SSLSocket) sf.createSocket(socket, host, port, true);
                verify(hv, host, sslSocket);

                return sslSocket;
            }
        };
    }
}
