//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.http2.client.http;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jetty.alpn.client.ALPNClientConnectionFactory;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.client.HttpDestination;
import org.eclipse.jetty.client.Origin;
import org.eclipse.jetty.client.ProxyConfiguration;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;

@ManagedObject("The HTTP/2 client transport")
public class HttpClientTransportOverHTTP2 extends ContainerLifeCycle implements HttpClientTransport
{
    private final HTTP2Client client;
    private ClientConnectionFactory connectionFactory;
    private HttpClient httpClient;
    private boolean useALPN = true;

    public HttpClientTransportOverHTTP2(HTTP2Client client)
    {
        this.client = client;
    }

    @ManagedAttribute(value = "The number of selectors", readonly = true)
    public int getSelectors()
    {
        return client.getSelectors();
    }

    public boolean isUseALPN()
    {
        return useALPN;
    }

    public void setUseALPN(boolean useALPN)
    {
        this.useALPN = useALPN;
    }

    @Override
    protected void doStart() throws Exception
    {
        if (!client.isStarted())
        {
            client.setExecutor(httpClient.getExecutor());
            client.setScheduler(httpClient.getScheduler());
            client.setByteBufferPool(httpClient.getByteBufferPool());
            client.setConnectTimeout(httpClient.getConnectTimeout());
            client.setIdleTimeout(httpClient.getIdleTimeout());
            client.setInputBufferSize(httpClient.getResponseBufferSize());
        }
        addBean(client);
        super.doStart();

        this.connectionFactory = new HTTP2ClientConnectionFactory();
        client.setClientConnectionFactory((endPoint, context) ->
        {
            HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
            return destination.getClientConnectionFactory().newConnection(endPoint, context);
        });
    }

    @Override
    protected void doStop() throws Exception
    {
        super.doStop();
        removeBean(client);
    }

    protected HttpClient getHttpClient()
    {
        return httpClient;
    }

    @Override
    public void setHttpClient(HttpClient client)
    {
        httpClient = client;
    }

    @Override
    public HttpDestination newHttpDestination(Origin origin)
    {
        return new HttpDestinationOverHTTP2(httpClient, origin);
    }

    @Override
    public void connect(InetSocketAddress address, Map<String, Object> context)
    {
        client.setConnectTimeout(httpClient.getConnectTimeout());

        SessionListenerPromise listenerPromise = new SessionListenerPromise(context);

        HttpDestinationOverHTTP2 destination = (HttpDestinationOverHTTP2)context.get(HTTP_DESTINATION_CONTEXT_KEY);
        SslContextFactory sslContextFactory = null;
        if (HttpScheme.HTTPS.is(destination.getScheme()))
            sslContextFactory = httpClient.getSslContextFactory();

        client.connect(sslContextFactory, address, listenerPromise, listenerPromise, context);
    }

    @Override
    public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
    {
        endPoint.setIdleTimeout(httpClient.getIdleTimeout());

        ClientConnectionFactory factory = connectionFactory;
        HttpDestinationOverHTTP2 destination = (HttpDestinationOverHTTP2)context.get(HTTP_DESTINATION_CONTEXT_KEY);
        ProxyConfiguration.Proxy proxy = destination.getProxy();
        boolean ssl = proxy == null ? HttpScheme.HTTPS.is(destination.getScheme()) : proxy.isSecure();
        if (ssl && isUseALPN())
            factory = new ALPNClientConnectionFactory(client.getExecutor(), factory, client.getProtocols());
        return factory.newConnection(endPoint, context);
    }

    protected HttpConnectionOverHTTP2 newHttpConnection(HttpDestination destination, Session session)
    {
        return new HttpConnectionOverHTTP2(destination, session);
    }

    protected void onClose(HttpConnectionOverHTTP2 connection, GoAwayFrame frame)
    {
        connection.close();
    }

    private class SessionListenerPromise extends Session.Listener.Adapter implements Promise<Session>
    {
        private final Map<String, Object> context;
        private HttpConnectionOverHTTP2 connection;

        private SessionListenerPromise(Map<String, Object> context)
        {
            this.context = context;
        }

        @Override
        public void succeeded(Session session)
        {
            connection = newHttpConnection(destination(), session);
            promise().succeeded(connection);
        }

        @Override
        public void failed(Throwable failure)
        {
            promise().failed(failure);
        }

        private HttpDestinationOverHTTP2 destination()
        {
            return (HttpDestinationOverHTTP2)context.get(HTTP_DESTINATION_CONTEXT_KEY);
        }

        @SuppressWarnings("unchecked")
        private Promise<Connection> promise()
        {
            return (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
        }

        @Override
        public Map<Integer, Integer> onPreface(Session session)
        {
            Map<Integer, Integer> settings = new HashMap<>();
            settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, client.getInitialStreamRecvWindow());
            return settings;
        }

        @Override
        public void onSettings(Session session, SettingsFrame frame)
        {
            Map<Integer, Integer> settings = frame.getSettings();
            if (settings.containsKey(SettingsFrame.MAX_CONCURRENT_STREAMS))
                destination().setMaxRequestsPerConnection(settings.get(SettingsFrame.MAX_CONCURRENT_STREAMS));
        }

        @Override
        public void onClose(Session session, GoAwayFrame frame)
        {
            HttpClientTransportOverHTTP2.this.onClose(connection, frame);
        }

        @Override
        public boolean onIdleTimeout(Session session)
        {
            return connection.onIdleTimeout(((HTTP2Session)session).getEndPoint().getIdleTimeout());
        }

        @Override
        public void onFailure(Session session, Throwable failure)
        {
            HttpConnectionOverHTTP2 c = connection;
            if (c != null)
                c.close(failure);
        }
    }
}
