//
//  ========================================================================
//  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.nio.channels.AsynchronousCloseException;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.jetty.client.HttpChannel;
import org.eclipse.jetty.client.HttpConnection;
import org.eclipse.jetty.client.HttpDestination;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.client.SendFailure;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ConcurrentHashSet;

public class HttpConnectionOverHTTP2 extends HttpConnection
{
    private final Set<HttpChannel> channels = new ConcurrentHashSet<>();
    private final AtomicBoolean closed = new AtomicBoolean();
    private final Session session;

    public HttpConnectionOverHTTP2(HttpDestination destination, Session session)
    {
        super(destination);
        this.session = session;
    }

    public Session getSession()
    {
        return session;
    }

    @Override
    protected SendFailure send(HttpExchange exchange)
    {
        exchange.getRequest().version(HttpVersion.HTTP_2);
        normalizeRequest(exchange.getRequest());

        // One connection maps to N channels, so for each exchange we create a new channel.
        HttpChannel channel = newHttpChannel(false);
        channels.add(channel);

        return send(channel, exchange);
    }

    protected HttpChannelOverHTTP2 newHttpChannel(boolean push)
    {
        return new HttpChannelOverHTTP2(getHttpDestination(), this, getSession(), push);
    }

    protected void release(HttpChannel channel)
    {
        channels.remove(channel);
        getHttpDestination().release(this);
    }

    @Override
    public boolean onIdleTimeout(long idleTimeout)
    {
        boolean close = super.onIdleTimeout(idleTimeout);
        if (close)
            close(new TimeoutException("idle_timeout"));
        return false;
    }

    @Override
    public void close()
    {
        close(new AsynchronousCloseException());
    }

    protected void close(Throwable failure)
    {
        if (closed.compareAndSet(false, true))
        {
            getHttpDestination().close(this);

            abort(failure);

            session.close(ErrorCode.NO_ERROR.code, failure.getMessage(), Callback.NOOP);
        }
    }

    @Override
    public boolean isClosed()
    {
        return closed.get();
    }

    private void abort(Throwable failure)
    {
        for (HttpChannel channel : channels)
        {
            HttpExchange exchange = channel.getHttpExchange();
            if (exchange != null)
                exchange.getRequest().abort(failure);
        }
        channels.clear();
    }

    @Override
    public String toString()
    {
        return String.format("%s@%h[%s]",
                getClass().getSimpleName(),
                this,
                session);
    }
}
