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

import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.SPDYException;
import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.api.StringDataInfo;
import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.generator.Generator;
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
import org.eclipse.jetty.toolchain.test.annotation.Slow;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.TimerScheduler;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AdvancedRunner.class)
//TODO: Uncomment comment lines and reimplement tests to fit new design
@Ignore("Doesn't work with new Flusher class, needs to be rewritten")
public class AsyncTimeoutTest
{
    EndPoint endPoint = new ByteArrayEndPoint();

    @Slow
    @Test
    public void testAsyncTimeoutInControlFrames() throws Exception
    {
        final long timeout = 1000;
        final TimeUnit unit = TimeUnit.MILLISECONDS;

        ByteBufferPool bufferPool = new MappedByteBufferPool();
        Executor threadPool = Executors.newCachedThreadPool();
        Scheduler scheduler = new TimerScheduler();
        scheduler.start(); // TODO need to use jetty lifecycles better here
        Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor());
        Session session = new StandardSession(SPDY.V2, bufferPool, scheduler, new TestController(),
                endPoint, null, 1, null, generator, new FlowControlStrategy.None())
        {
//            @Override
            public void flush()
            {
                try
                {
                    unit.sleep(2 * timeout);
//                    super.flush();
                }
                catch (InterruptedException x)
                {
                    throw new SPDYException(x);
                }
            }
        };

        final CountDownLatch failedLatch = new CountDownLatch(1);
        session.syn(new SynInfo(timeout, unit, new Fields(), true, (byte)0), null, new Promise.Adapter<Stream>()
        {
            @Override
            public void failed(Throwable x)
            {
                failedLatch.countDown();
            }
        });

        Assert.assertTrue(failedLatch.await(2 * timeout, unit));
    }

    @Slow
    @Test
    public void testAsyncTimeoutInDataFrames() throws Exception
    {
        final long timeout = 1000;
        final TimeUnit unit = TimeUnit.MILLISECONDS;

        ByteBufferPool bufferPool = new MappedByteBufferPool();
        Executor threadPool = Executors.newCachedThreadPool();
        Scheduler scheduler = new TimerScheduler();
        scheduler.start();
        Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor());
        Session session = new StandardSession(SPDY.V2, bufferPool, scheduler, new TestController(),
                endPoint, null, 1, null, generator, new FlowControlStrategy.None())
        {
//            @Override
            protected void write(ByteBuffer buffer, Callback callback)
            {
                try
                {
                    // Wait if we're writing the data frame (control frame's first byte is 0x80)
                    if (buffer.get(0) == 0)
                        unit.sleep(2 * timeout);
//                    super.write(buffer, callback);
                }
                catch (InterruptedException x)
                {
                    throw new SPDYException(x);
                }
            }
        };

        Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
        final CountDownLatch failedLatch = new CountDownLatch(1);
        stream.data(new StringDataInfo(timeout, unit, "data", true), new Callback.Adapter()
        {
            @Override
            public void failed(Throwable x)
            {
                failedLatch.countDown();
            }
        });

        Assert.assertTrue(failedLatch.await(2 * timeout, unit));
    }

    private static class TestController implements Controller
    {
        @Override
        public void write(Callback callback, ByteBuffer... buffers)
        {
            callback.succeeded();
        }

        @Override
        public void close(boolean onlyOutput)
        {
        }
    }
}
