//
//  ========================================================================
//  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;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.junit.Assert;
import org.junit.Test;

public class StreamCountTest extends AbstractTest
{
    @Test
    public void testServerAllowsOneStreamEnforcedByClient() throws Exception
    {
        start(new ServerSessionListener.Adapter()
        {
            @Override
            public Map<Integer, Integer> onPreface(Session session)
            {
                Map<Integer, Integer> settings = new HashMap<>();
                settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, 1);
                return settings;
            }

            @Override
            public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
            {
                return new Stream.Listener.Adapter()
                {
                    @Override
                    public void onData(Stream stream, DataFrame frame, Callback callback)
                    {
                        if (frame.isEndStream())
                        {
                            HttpFields fields = new HttpFields();
                            MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, fields);
                            stream.headers(new HeadersFrame(stream.getId(), metaData, null, true), callback);
                        }
                        else
                        {
                            callback.succeeded();
                        }
                    }
                };
            }
        });

        final CountDownLatch settingsLatch = new CountDownLatch(1);
        Session session = newClient(new Session.Listener.Adapter()
        {
            @Override
            public void onSettings(Session session, SettingsFrame frame)
            {
                settingsLatch.countDown();
            }
        });

        Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));

        HttpFields fields = new HttpFields();
        MetaData.Request metaData = newRequest("GET", fields);
        HeadersFrame frame1 = new HeadersFrame(metaData, null, false);
        FuturePromise<Stream> streamPromise1 = new FuturePromise<>();
        final CountDownLatch responseLatch = new CountDownLatch(1);
        session.newStream(frame1, streamPromise1, new Stream.Listener.Adapter()
        {
            @Override
            public void onHeaders(Stream stream, HeadersFrame frame)
            {
                if (frame.isEndStream())
                    responseLatch.countDown();
            }
        });
        Stream stream1 = streamPromise1.get(5, TimeUnit.SECONDS);

        HeadersFrame frame2 = new HeadersFrame(metaData, null, false);
        FuturePromise<Stream> streamPromise2 = new FuturePromise<>();
        session.newStream(frame2, streamPromise2, new Stream.Listener.Adapter());

        try
        {
            streamPromise2.get(5, TimeUnit.SECONDS);
            Assert.fail();
        }
        catch (ExecutionException x)
        {
            // Expected
        }

        stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP);
        Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
    }

    @Test
    public void testServerAllowsOneStreamEnforcedByServer() throws Exception
    {
        final CountDownLatch resetLatch = new CountDownLatch(1);
        start(new ServerSessionListener.Adapter()
        {
            @Override
            public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
            {
                HTTP2Session session = (HTTP2Session)stream.getSession();
                session.setMaxRemoteStreams(1);

                return new Stream.Listener.Adapter()
                {
                    @Override
                    public void onData(Stream stream, DataFrame frame, Callback callback)
                    {
                        if (frame.isEndStream())
                        {
                            HttpFields fields = new HttpFields();
                            MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, fields);
                            stream.headers(new HeadersFrame(stream.getId(), metaData, null, true), callback);
                        }
                        else
                        {
                            callback.succeeded();
                        }
                    }
                };
            }
        });

        Session session = newClient(new Session.Listener.Adapter());

        HttpFields fields = new HttpFields();
        MetaData.Request metaData = newRequest("GET", fields);
        HeadersFrame frame1 = new HeadersFrame(metaData, null, false);
        FuturePromise<Stream> streamPromise1 = new FuturePromise<>();
        final CountDownLatch responseLatch = new CountDownLatch(1);
        session.newStream(frame1, streamPromise1, new Stream.Listener.Adapter()
        {
            @Override
            public void onHeaders(Stream stream, HeadersFrame frame)
            {
                if (frame.isEndStream())
                    responseLatch.countDown();
            }
        });

        Stream stream1 = streamPromise1.get(5, TimeUnit.SECONDS);

        HeadersFrame frame2 = new HeadersFrame(metaData, null, false);
        FuturePromise<Stream> streamPromise2 = new FuturePromise<>();
        session.newStream(frame2, streamPromise2, new Stream.Listener.Adapter()
        {
            @Override
            public void onReset(Stream stream, ResetFrame frame)
            {
                resetLatch.countDown();
            }
        });

        streamPromise2.get(5, TimeUnit.SECONDS);
        Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));

        stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP);
        Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
    }
}
