/*
 *  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.harmony.luni.internal.net.www.protocol.https;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import java.security.Permission;
import java.security.Principal;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;

import org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection;
import org.apache.harmony.luni.internal.nls.Messages;

/**
 * HttpsURLConnection implementation.
 */
public class HttpsURLConnection extends javax.net.ssl.HttpsURLConnection {

    // Https engine to be wrapped
    private final HttpsEngine httpsEngine;

    // SSLSocket to be used for connection
    private SSLSocket sslSocket;

    protected HttpsURLConnection(URL url, int port) {
        super(url);
        httpsEngine = new HttpsEngine(url, port);
    }

    protected HttpsURLConnection(URL url, int port, Proxy proxy) {
        super(url);
        httpsEngine = new HttpsEngine(url, port, proxy);
    }

    @Override
    public String getCipherSuite() {
        if (sslSocket == null) {
            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
        }
        return sslSocket.getSession().getCipherSuite();
    }

    @Override
    public Certificate[] getLocalCertificates() {
        if (sslSocket == null) {
            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
        }
        return sslSocket.getSession().getLocalCertificates();
    }

    @Override
    public Certificate[] getServerCertificates()
            throws SSLPeerUnverifiedException {
        if (sslSocket == null) {
            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
        }
        return sslSocket.getSession().getPeerCertificates();
    }

    @Override
    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
        if (sslSocket == null) {
            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
        }
        return sslSocket.getSession().getPeerPrincipal();
    }

    @Override
    public Principal getLocalPrincipal() {
        if (sslSocket == null) {
            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
        }
        return sslSocket.getSession().getLocalPrincipal();
    }

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

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

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

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

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

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

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

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

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

    @Override
    public void connect() throws IOException {
        httpsEngine.connect();
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override
    public void setConnectTimeout(int timeout) {
        httpsEngine.setConnectTimeout(timeout);
    }

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

    @Override
    public void setReadTimeout(int timeout) {
        httpsEngine.setReadTimeout(timeout);
    }

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

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

    /**
     * HttpsEngine
     */
    private class HttpsEngine extends HttpURLConnection {

        // In case of using proxy this field indicates
        // if it is a SSL Tunnel establishing stage
        private boolean makingSSLTunnel;

        protected HttpsEngine(URL url, int port) {
            super(url, port);
        }

        protected HttpsEngine(URL url, int port, Proxy proxy) {
            super(url, port, proxy);
        }

        @Override
        public void connect() throws IOException {
            if (connected) {
                return;
            }
            if (usingProxy() && !makingSSLTunnel) {
                // SSL Tunnel through the proxy was not established yet, do so
                makingSSLTunnel = true;
                // first - make the connection
                super.connect();
                // keep request method
                String save_meth = method;
                // make SSL Tunnel
                method = "CONNECT"; //$NON-NLS-1$
                try {
                    doRequest();
                    endRequest();
                } finally {
                    // restore initial request method
                    method = save_meth;
                }
                if (!connected) {
                    throw new IOException(Messages.getString("luni.01", //$NON-NLS-1$
                            responseMessage, responseCode));
                }
                // if there are some remaining data in the stream - read it out
                InputStream is = connection.getInputStream();
                while (is.available() != 0) {
                    is.read();
                }
                makingSSLTunnel = false;
            } else {
                // no need in SSL tunnel
                super.connect();
            }
            if (!makingSSLTunnel) {
                sslSocket = connection.getSecureSocket(getSSLSocketFactory(), getHostnameVerifier());
                setUpTransportIO(connection);
            }
        }

        @Override
        protected String requestString() {
            if (usingProxy()) {
                if (makingSSLTunnel) {
                    // we are making the SSL Tunneling, return remotehost:port
                    int port = url.getPort();
                    return (port > 0) ? url.getHost() + ":" + port //$NON-NLS-1$
                    : url.getHost();
                }
                // we has made SSL Tunneling, return /requested.data
                String file = url.getFile();
                if (file == null || file.length() == 0) {
                    file = "/"; //$NON-NLS-1$
                }
                return file;
            }
            return super.requestString();
        }

    }
}
