/*
 *  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 libcore.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.CacheResponse;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.SecureCacheResponse;
import java.net.URL;
import java.security.Permission;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

final class HttpsURLConnectionImpl extends HttpsURLConnection {

    /** HttpUrlConnectionDelegate allows reuse of HttpURLConnectionImpl */
    private final HttpUrlConnectionDelegate delegate;

    protected HttpsURLConnectionImpl(URL url, int port) {
        super(url);
        delegate = new HttpUrlConnectionDelegate(url, port);
    }

    protected HttpsURLConnectionImpl(URL url, int port, Proxy proxy) {
        super(url);
        delegate = new HttpUrlConnectionDelegate(url, port, proxy);
    }

    private void checkConnected() {
        if (delegate.getSSLSocket() == null) {
            throw new IllegalStateException("Connection has not yet been established");
        }
    }

    HttpEngine getHttpEngine() {
        return delegate.getHttpEngine();
    }

    @Override
    public String getCipherSuite() {
        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
        if (cacheResponse != null) {
            return cacheResponse.getCipherSuite();
        }
        checkConnected();
        return delegate.getSSLSocket().getSession().getCipherSuite();
    }

    @Override
    public Certificate[] getLocalCertificates() {
        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
        if (cacheResponse != null) {
            List<Certificate> result = cacheResponse.getLocalCertificateChain();
            return result != null ? result.toArray(new Certificate[result.size()]) : null;
        }
        checkConnected();
        return delegate.getSSLSocket().getSession().getLocalCertificates();
    }

    @Override
    public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
        if (cacheResponse != null) {
            List<Certificate> result = cacheResponse.getServerCertificateChain();
            return result != null ? result.toArray(new Certificate[result.size()]) : null;
        }
        checkConnected();
        return delegate.getSSLSocket().getSession().getPeerCertificates();
    }

    @Override
    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
        if (cacheResponse != null) {
            return cacheResponse.getPeerPrincipal();
        }
        checkConnected();
        return delegate.getSSLSocket().getSession().getPeerPrincipal();
    }

    @Override
    public Principal getLocalPrincipal() {
        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
        if (cacheResponse != null) {
            return cacheResponse.getLocalPrincipal();
        }
        checkConnected();
        return delegate.getSSLSocket().getSession().getLocalPrincipal();
    }

    @Override
    public void disconnect() {
        delegate.disconnect();
    }

    @Override
    public InputStream getErrorStream() {
        return delegate.getErrorStream();
    }

    @Override
    public String getRequestMethod() {
        return delegate.getRequestMethod();
    }

    @Override
    public int getResponseCode() throws IOException {
        return delegate.getResponseCode();
    }

    @Override
    public String getResponseMessage() throws IOException {
        return delegate.getResponseMessage();
    }

    @Override
    public void setRequestMethod(String method) throws ProtocolException {
        delegate.setRequestMethod(method);
    }

    @Override
    public boolean usingProxy() {
        return delegate.usingProxy();
    }

    @Override
    public boolean getInstanceFollowRedirects() {
        return delegate.getInstanceFollowRedirects();
    }

    @Override
    public void setInstanceFollowRedirects(boolean followRedirects) {
        delegate.setInstanceFollowRedirects(followRedirects);
    }

    @Override
    public void connect() throws IOException {
        connected = true;
        delegate.connect();
    }

    @Override
    public boolean getAllowUserInteraction() {
        return delegate.getAllowUserInteraction();
    }

    @Override
    public Object getContent() throws IOException {
        return delegate.getContent();
    }

    @SuppressWarnings("unchecked") // Spec does not generify
    @Override
    public Object getContent(Class[] types) throws IOException {
        return delegate.getContent(types);
    }

    @Override
    public String getContentEncoding() {
        return delegate.getContentEncoding();
    }

    @Override
    public int getContentLength() {
        return delegate.getContentLength();
    }

    @Override
    public String getContentType() {
        return delegate.getContentType();
    }

    @Override
    public long getDate() {
        return delegate.getDate();
    }

    @Override
    public boolean getDefaultUseCaches() {
        return delegate.getDefaultUseCaches();
    }

    @Override
    public boolean getDoInput() {
        return delegate.getDoInput();
    }

    @Override
    public boolean getDoOutput() {
        return delegate.getDoOutput();
    }

    @Override
    public long getExpiration() {
        return delegate.getExpiration();
    }

    @Override
    public String getHeaderField(int pos) {
        return delegate.getHeaderField(pos);
    }

    @Override
    public Map<String, List<String>> getHeaderFields() {
        return delegate.getHeaderFields();
    }

    @Override
    public Map<String, List<String>> getRequestProperties() {
        return delegate.getRequestProperties();
    }

    @Override
    public void addRequestProperty(String field, String newValue) {
        delegate.addRequestProperty(field, newValue);
    }

    @Override
    public String getHeaderField(String key) {
        return delegate.getHeaderField(key);
    }

    @Override
    public long getHeaderFieldDate(String field, long defaultValue) {
        return delegate.getHeaderFieldDate(field, defaultValue);
    }

    @Override
    public int getHeaderFieldInt(String field, int defaultValue) {
        return delegate.getHeaderFieldInt(field, defaultValue);
    }

    @Override
    public String getHeaderFieldKey(int posn) {
        return delegate.getHeaderFieldKey(posn);
    }

    @Override
    public long getIfModifiedSince() {
        return delegate.getIfModifiedSince();
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return delegate.getInputStream();
    }

    @Override
    public long getLastModified() {
        return delegate.getLastModified();
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        return delegate.getOutputStream();
    }

    @Override
    public Permission getPermission() throws IOException {
        return delegate.getPermission();
    }

    @Override
    public String getRequestProperty(String field) {
        return delegate.getRequestProperty(field);
    }

    @Override
    public URL getURL() {
        return delegate.getURL();
    }

    @Override
    public boolean getUseCaches() {
        return delegate.getUseCaches();
    }

    @Override
    public void setAllowUserInteraction(boolean newValue) {
        delegate.setAllowUserInteraction(newValue);
    }

    @Override
    public void setDefaultUseCaches(boolean newValue) {
        delegate.setDefaultUseCaches(newValue);
    }

    @Override
    public void setDoInput(boolean newValue) {
        delegate.setDoInput(newValue);
    }

    @Override
    public void setDoOutput(boolean newValue) {
        delegate.setDoOutput(newValue);
    }

    @Override
    public void setIfModifiedSince(long newValue) {
        delegate.setIfModifiedSince(newValue);
    }

    @Override
    public void setRequestProperty(String field, String newValue) {
        delegate.setRequestProperty(field, newValue);
    }

    @Override
    public void setUseCaches(boolean newValue) {
        delegate.setUseCaches(newValue);
    }

    @Override
    public void setConnectTimeout(int timeoutMillis) {
        delegate.setConnectTimeout(timeoutMillis);
    }

    @Override
    public int getConnectTimeout() {
        return delegate.getConnectTimeout();
    }

    @Override
    public void setReadTimeout(int timeoutMillis) {
        delegate.setReadTimeout(timeoutMillis);
    }

    @Override
    public int getReadTimeout() {
        return delegate.getReadTimeout();
    }

    @Override
    public String toString() {
        return delegate.toString();
    }

    @Override
    public void setFixedLengthStreamingMode(int contentLength) {
        delegate.setFixedLengthStreamingMode(contentLength);
    }

    @Override
    public void setChunkedStreamingMode(int chunkLength) {
        delegate.setChunkedStreamingMode(chunkLength);
    }

    private final class HttpUrlConnectionDelegate extends HttpURLConnectionImpl {
        private HttpUrlConnectionDelegate(URL url, int port) {
            super(url, port);
        }

        private HttpUrlConnectionDelegate(URL url, int port, Proxy proxy) {
            super(url, port, proxy);
        }

        @Override protected HttpEngine newHttpEngine(String method, RawHeaders requestHeaders,
                HttpConnection connection, RetryableOutputStream requestBody) throws IOException {
            return new HttpsEngine(this, method, requestHeaders, connection, requestBody,
                    HttpsURLConnectionImpl.this);
        }

        public SecureCacheResponse getCacheResponse() {
            HttpsEngine engine = (HttpsEngine) httpEngine;
            return engine != null ? (SecureCacheResponse) engine.getCacheResponse() : null;
        }

        public SSLSocket getSSLSocket() {
            HttpsEngine engine = (HttpsEngine) httpEngine;
            return engine != null ? engine.sslSocket : null;
        }
    }

    private static class HttpsEngine extends HttpEngine {

        /**
         * Local stash of HttpsEngine.connection.sslSocket for answering
         * queries such as getCipherSuite even after
         * httpsEngine.Connection has been recycled. It's presence is also
         * used to tell if the HttpsURLConnection is considered connected,
         * as opposed to the connected field of URLConnection or the a
         * non-null connect in HttpURLConnectionImpl
         */
        private SSLSocket sslSocket;

        private final HttpsURLConnectionImpl enclosing;

        /**
         * @param policy the HttpURLConnectionImpl with connection configuration
         * @param enclosing the HttpsURLConnection with HTTPS features
         */
        private HttpsEngine(HttpURLConnectionImpl policy, String method, RawHeaders requestHeaders,
                HttpConnection connection, RetryableOutputStream requestBody,
                HttpsURLConnectionImpl enclosing) throws IOException {
            super(policy, method, requestHeaders, connection, requestBody);
            this.sslSocket = connection != null ? connection.getSecureSocketIfConnected() : null;
            this.enclosing = enclosing;
        }

        @Override protected void connect() throws IOException {
            // first try an SSL connection with compression and
            // various TLS extensions enabled, if it fails (and its
            // not unheard of that it will) fallback to a more
            // barebones connections
            boolean connectionReused;
            try {
                connectionReused = makeSslConnection(true);
            } catch (IOException e) {
                // If the problem was a CertificateException from the X509TrustManager,
                // do not retry, we didn't have an abrupt server initiated exception.
                if (e instanceof SSLHandshakeException
                        && e.getCause() instanceof CertificateException) {
                    throw e;
                }
                release(false);
                connectionReused = makeSslConnection(false);
            }

            if (!connectionReused) {
                sslSocket = connection.verifySecureSocketHostname(enclosing.getHostnameVerifier());
            }
        }

        /**
         * Attempt to make an https connection. Returns true if a
         * connection was reused, false otherwise.
         *
         * @param tlsTolerant If true, assume server can handle common
         * TLS extensions and SSL deflate compression. If false, use
         * an SSL3 only fallback mode without compression.
         */
        private boolean makeSslConnection(boolean tlsTolerant) throws IOException {
            // make an SSL Tunnel on the first message pair of each SSL + proxy connection
            if (connection == null) {
                connection = openSocketConnection();
                if (connection.getAddress().getProxy() != null) {
                    makeTunnel(policy, connection, getRequestHeaders());
                }
            }

            // if super.makeConnection returned a connection from the
            // pool, sslSocket needs to be initialized here. If it is
            // a new connection, it will be initialized by
            // getSecureSocket below.
            sslSocket = connection.getSecureSocketIfConnected();

            // we already have an SSL connection,
            if (sslSocket != null) {
                return true;
            }

            connection.setupSecureSocket(enclosing.getSSLSocketFactory(), tlsTolerant);
            return false;
        }

        /**
         * To make an HTTPS connection over an HTTP proxy, send an unencrypted
         * CONNECT request to create the proxy connection. This may need to be
         * retried if the proxy requires authorization.
         */
        private void makeTunnel(HttpURLConnectionImpl policy, HttpConnection connection,
                RequestHeaders requestHeaders) throws IOException {
            RawHeaders rawRequestHeaders = requestHeaders.getHeaders();
            while (true) {
                HttpEngine connect = new ProxyConnectEngine(policy, rawRequestHeaders, connection);
                connect.sendRequest();
                connect.readResponse();

                int responseCode = connect.getResponseCode();
                switch (connect.getResponseCode()) {
                case HTTP_OK:
                    return;
                case HTTP_PROXY_AUTH:
                    rawRequestHeaders = new RawHeaders(rawRequestHeaders);
                    boolean credentialsFound = policy.processAuthHeader(HTTP_PROXY_AUTH,
                            connect.getResponseHeaders(), rawRequestHeaders);
                    if (credentialsFound) {
                        continue;
                    } else {
                        throw new IOException("Failed to authenticate with proxy");
                    }
                default:
                    throw new IOException("Unexpected response code for CONNECT: " + responseCode);
                }
            }
        }

        @Override protected boolean acceptCacheResponseType(CacheResponse cacheResponse) {
            return cacheResponse instanceof SecureCacheResponse;
        }

        @Override protected boolean includeAuthorityInRequestLine() {
            // Even if there is a proxy, it isn't involved. Always request just the file.
            return false;
        }

        @Override protected SSLSocketFactory getSslSocketFactory() {
            return enclosing.getSSLSocketFactory();
        }

        @Override protected HttpURLConnection getHttpConnectionToCache() {
            return enclosing;
        }
    }

    private static class ProxyConnectEngine extends HttpEngine {
        public ProxyConnectEngine(HttpURLConnectionImpl policy, RawHeaders requestHeaders,
                HttpConnection connection) throws IOException {
            super(policy, HttpEngine.CONNECT, requestHeaders, connection, null);
        }

        /**
         * If we're establishing an HTTPS tunnel with CONNECT (RFC 2817 5.2), send
         * only the minimum set of headers. This avoids sending potentially
         * sensitive data like HTTP cookies to the proxy unencrypted.
         */
        @Override protected RawHeaders getNetworkRequestHeaders() throws IOException {
            RequestHeaders privateHeaders = getRequestHeaders();
            URL url = policy.getURL();

            RawHeaders result = new RawHeaders();
            result.setStatusLine("CONNECT " + url.getHost() + ":" + url.getEffectivePort()
                    + " HTTP/1.1");

            // Always set Host and User-Agent.
            String host = privateHeaders.getHost();
            if (host == null) {
                host = getOriginAddress(url);
            }
            result.set("Host", host);

            String userAgent = privateHeaders.getUserAgent();
            if (userAgent == null) {
                userAgent = getDefaultUserAgent();
            }
            result.set("User-Agent", userAgent);

            // Copy over the Proxy-Authorization header if it exists.
            String proxyAuthorization = privateHeaders.getProxyAuthorization();
            if (proxyAuthorization != null) {
                result.set("Proxy-Authorization", proxyAuthorization);
            }

            // Always set the Proxy-Connection to Keep-Alive for the benefit of
            // HTTP/1.0 proxies like Squid.
            result.set("Proxy-Connection", "Keep-Alive");
            return result;
        }

        @Override protected boolean requiresTunnel() {
            return true;
        }
    }
}
