/*
 * ====================================================================
 * 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
package org.apache.http.impl.nio.conn;

import java.io.IOException;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLSession;

import org.apache.http.HttpConnectionMetrics;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseFactory;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.routing.RouteTracker;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.conn.ConnectionShutdownException;
import org.apache.http.impl.nio.reactor.SSLIOSession;
import org.apache.http.impl.nio.reactor.SSLMode;
import org.apache.http.nio.conn.ClientConnectionManager;
import org.apache.http.nio.conn.ManagedClientConnection;
import org.apache.http.nio.conn.OperatedClientConnection;
import org.apache.http.nio.conn.scheme.LayeringStrategy;
import org.apache.http.nio.conn.scheme.Scheme;
import org.apache.http.nio.reactor.IOSession;
import org.apache.http.nio.util.ByteBufferAllocator;
import org.apache.http.nio.util.HeapByteBufferAllocator;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

class ManagedClientConnectionImpl implements ManagedClientConnection {

    private final ClientConnectionManager manager;
    private volatile HttpPoolEntry poolEntry;
    private volatile boolean reusable;
    private volatile long duration;

    public ManagedClientConnectionImpl(
            final ClientConnectionManager manager,
            final HttpPoolEntry poolEntry) {
        super();
        this.manager = manager;
        this.poolEntry = poolEntry;
        this.reusable = true;
        this.duration = Long.MAX_VALUE;
    }

    HttpPoolEntry getPoolEntry() {
        return this.poolEntry;
    }

    HttpPoolEntry detach() {
        HttpPoolEntry local = this.poolEntry;
        this.poolEntry = null;
        return local;
    }

    public ClientConnectionManager getManager() {
        return this.manager;
    }

    private OperatedClientConnection getConnection() {
        HttpPoolEntry local = this.poolEntry;
        if (local == null) {
            return null;
        }
        IOSession session = local.getConnection();
        return (OperatedClientConnection) session.getAttribute(
                ExecutionContext.HTTP_CONNECTION);
    }

    private OperatedClientConnection ensureConnection() {
        HttpPoolEntry local = this.poolEntry;
        if (local == null) {
            throw new ConnectionShutdownException();
        }
        IOSession session = local.getConnection();
        return (OperatedClientConnection) session.getAttribute(
                ExecutionContext.HTTP_CONNECTION);
    }

    private HttpPoolEntry ensurePoolEntry() {
        HttpPoolEntry local = this.poolEntry;
        if (local == null) {
            throw new ConnectionShutdownException();
        }
        return local;
    }

    public void close() throws IOException {
        OperatedClientConnection conn = getConnection();
        if (conn != null) {
            conn.close();
        }
    }

    public void shutdown() throws IOException {
        OperatedClientConnection conn = getConnection();
        if (conn != null) {
            conn.shutdown();
        }
    }

    public boolean isOpen() {
        OperatedClientConnection conn = getConnection();
        if (conn != null) {
            return conn.isOpen();
        } else {
            return false;
        }
    }

    public boolean isStale() {
        return isOpen();
    }

    public void setSocketTimeout(int timeout) {
        OperatedClientConnection conn = ensureConnection();
        conn.setSocketTimeout(timeout);
    }

    public int getSocketTimeout() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getSocketTimeout();
    }

    public HttpConnectionMetrics getMetrics() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getMetrics();
    }

    public InetAddress getLocalAddress() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getLocalAddress();
    }

    public int getLocalPort() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getLocalPort();
    }

    public InetAddress getRemoteAddress() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getRemoteAddress();
    }

    public int getRemotePort() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getRemotePort();
    }

    public int getStatus() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getStatus();
    }

    public HttpRequest getHttpRequest() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getHttpRequest();
    }

    public HttpResponse getHttpResponse() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getHttpResponse();
    }

    public HttpContext getContext() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getContext();
    }

    public void requestInput() {
        OperatedClientConnection conn = ensureConnection();
        conn.requestInput();
    }

    public void suspendInput() {
        OperatedClientConnection conn = ensureConnection();
        conn.suspendInput();
    }

    public void requestOutput() {
        OperatedClientConnection conn = ensureConnection();
        conn.requestOutput();
    }

    public void suspendOutput() {
        OperatedClientConnection conn = ensureConnection();
        conn.suspendOutput();
    }

    public void submitRequest(final HttpRequest request) throws IOException, HttpException {
        OperatedClientConnection conn = ensureConnection();
        conn.submitRequest(request);
    }

    public boolean isRequestSubmitted() {
        OperatedClientConnection conn = ensureConnection();
        return conn.isRequestSubmitted();
    }

    public void resetOutput() {
        OperatedClientConnection conn = ensureConnection();
        conn.resetOutput();
    }

    public void resetInput() {
        OperatedClientConnection conn = ensureConnection();
        conn.resetInput();
    }

    public boolean isSecure() {
        OperatedClientConnection conn = ensureConnection();
        return conn.getSSLIOSession() != null;
    }

    public HttpRoute getRoute() {
        HttpPoolEntry entry = ensurePoolEntry();
        return entry.getEffectiveRoute();
    }

    public SSLSession getSSLSession() {
        OperatedClientConnection conn = ensureConnection();
        SSLIOSession iosession = conn.getSSLIOSession();
        return iosession != null ? iosession.getSSLSession() : null;
    }

    public Object getState() {
        HttpPoolEntry entry = ensurePoolEntry();
        return entry.getState();
    }

    public void setState(final Object state) {
        HttpPoolEntry entry = ensurePoolEntry();
        entry.setState(state);
    }

    public void markReusable() {
        this.reusable = true;
    }

    public void unmarkReusable() {
        this.reusable = false;
    }

    public boolean isMarkedReusable() {
        return this.reusable;
    }

    public void setIdleDuration(long duration, TimeUnit unit) {
        if(duration > 0) {
            this.duration = unit.toMillis(duration);
        } else {
            this.duration = -1;
        }
    }

    protected ByteBufferAllocator createByteBufferAllocator() {
        return new HeapByteBufferAllocator();
    }

    protected HttpResponseFactory createHttpResponseFactory() {
        return new DefaultHttpResponseFactory();
    }

    public synchronized void open(
            final HttpRoute route,
            final HttpContext context, final HttpParams params) throws IOException {
        HttpPoolEntry entry = ensurePoolEntry();
        RouteTracker tracker = entry.getTracker();
        if (tracker.isConnected()) {
            throw new IllegalStateException("Connection already open");
        }

        HttpHost target = route.getTargetHost();
        HttpHost proxy = route.getProxyHost();
        IOSession iosession = entry.getConnection();

        if (proxy == null) {
            Scheme scheme = this.manager.getSchemeRegistry().getScheme(target);
            LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
            if (layeringStrategy != null) {
                SSLIOSession ssliosession = (SSLIOSession) layeringStrategy.layer(iosession);
                ssliosession.bind(SSLMode.CLIENT, params);
                iosession = ssliosession;
            }
        }

        OperatedClientConnection conn = new DefaultClientConnection(
                "http-outgoing-" + entry.getId(),
                iosession,
                createHttpResponseFactory(),
                createByteBufferAllocator(),
                params);
        iosession.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);

        if (proxy == null) {
            tracker.connectTarget(conn.getSSLIOSession() != null);
        } else {
            tracker.connectProxy(proxy, false);
        }
    }

    public synchronized void tunnelProxy(
            final HttpHost next, final HttpParams params) throws IOException {
        HttpPoolEntry entry = ensurePoolEntry();
        RouteTracker tracker = entry.getTracker();
        if (!tracker.isConnected()) {
            throw new IllegalStateException("Connection not open");
        }
        tracker.tunnelProxy(next, false);
    }

    public synchronized void tunnelTarget(
            final HttpParams params) throws IOException {
        HttpPoolEntry entry = ensurePoolEntry();
        RouteTracker tracker = entry.getTracker();
        if (!tracker.isConnected()) {
            throw new IllegalStateException("Connection not open");
        }
        if (tracker.isTunnelled()) {
            throw new IllegalStateException("Connection is already tunnelled");
        }
        tracker.tunnelTarget(false);
    }

    public synchronized void layerProtocol(
            final HttpContext context, final HttpParams params) throws IOException {
        HttpPoolEntry entry = ensurePoolEntry();
        RouteTracker tracker = entry.getTracker();
        if (!tracker.isConnected()) {
            throw new IllegalStateException("Connection not open");
        }
        if (!tracker.isTunnelled()) {
            throw new IllegalStateException("Protocol layering without a tunnel not supported");
        }
        if (tracker.isLayered()) {
            throw new IllegalStateException("Multiple protocol layering not supported");
        }
        HttpHost target = tracker.getTargetHost();
        Scheme scheme = this.manager.getSchemeRegistry().getScheme(target);
        LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
        if (layeringStrategy == null) {
            throw new IllegalStateException(scheme.getName() +
                    " scheme does not provider support for protocol layering");
        }
        IOSession iosession = entry.getConnection();
        SSLIOSession ssliosession = (SSLIOSession) layeringStrategy.layer(iosession);
        ssliosession.bind(SSLMode.CLIENT, params);

        OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute(
                ExecutionContext.HTTP_CONNECTION);
        conn.upgrade(ssliosession);
        tracker.layerProtocol(layeringStrategy.isSecure());
    }

    public synchronized void releaseConnection() {
        if (this.poolEntry == null) {
            return;
        }
        this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
        this.poolEntry = null;
    }

    public synchronized void abortConnection() {
        if (this.poolEntry == null) {
            return;
        }
        this.reusable = false;
        IOSession iosession = this.poolEntry.getConnection();
        OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute(
                ExecutionContext.HTTP_CONNECTION);
        try {
            conn.shutdown();
        } catch (IOException ignore) {
        }
        this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
        this.poolEntry = null;
    }

}
