/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 * Other contributors include Andrew Wright, Jeffrey Hayes,
 * Pat Fisher, Mike Judd.
 */

package jsr166;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeoutException;

import junit.framework.Test;
import junit.framework.TestSuite;

public class ExchangerTest extends JSR166TestCase {

    // android-note: Removed because the CTS runner does a bad job of
    // retrying tests that have suite() declarations.
    //
    // public static void main(String[] args) {
    //     main(suite(), args);
    // }
    // public static Test suite() {
    //     return new TestSuite(...);
    // }

    /**
     * exchange exchanges objects across two threads
     */
    public void testExchange() {
        final Exchanger e = new Exchanger();
        Thread t1 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws InterruptedException {
                assertSame(one, e.exchange(two));
                assertSame(two, e.exchange(one));
            }});
        Thread t2 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws InterruptedException {
                assertSame(two, e.exchange(one));
                assertSame(one, e.exchange(two));
            }});

        awaitTermination(t1);
        awaitTermination(t2);
    }

    /**
     * timed exchange exchanges objects across two threads
     */
    public void testTimedExchange() {
        final Exchanger e = new Exchanger();
        Thread t1 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws Exception {
                assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
                assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
            }});
        Thread t2 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws Exception {
                assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
                assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
            }});

        awaitTermination(t1);
        awaitTermination(t2);
    }

    /**
     * interrupt during wait for exchange throws IE
     */
    public void testExchange_InterruptedException() {
        final Exchanger e = new Exchanger();
        final CountDownLatch threadStarted = new CountDownLatch(1);
        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
            public void realRun() throws InterruptedException {
                threadStarted.countDown();
                e.exchange(one);
            }});

        await(threadStarted);
        t.interrupt();
        awaitTermination(t);
    }

    /**
     * interrupt during wait for timed exchange throws IE
     */
    public void testTimedExchange_InterruptedException() {
        final Exchanger e = new Exchanger();
        final CountDownLatch threadStarted = new CountDownLatch(1);
        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
            public void realRun() throws Exception {
                threadStarted.countDown();
                e.exchange(null, LONG_DELAY_MS, MILLISECONDS);
            }});

        await(threadStarted);
        t.interrupt();
        awaitTermination(t);
    }

    /**
     * timeout during wait for timed exchange throws TimeoutException
     */
    public void testExchange_TimeoutException() {
        final Exchanger e = new Exchanger();
        Thread t = newStartedThread(new CheckedRunnable() {
            public void realRun() throws Exception {
                long startTime = System.nanoTime();
                try {
                    e.exchange(null, timeoutMillis(), MILLISECONDS);
                    shouldThrow();
                } catch (TimeoutException success) {}
                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
            }});

        awaitTermination(t);
    }

    /**
     * If one exchanging thread is interrupted, another succeeds.
     */
    public void testReplacementAfterExchange() {
        final Exchanger e = new Exchanger();
        final CountDownLatch exchanged = new CountDownLatch(2);
        final CountDownLatch interrupted = new CountDownLatch(1);
        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
            public void realRun() throws InterruptedException {
                assertSame(two, e.exchange(one));
                exchanged.countDown();
                e.exchange(two);
            }});
        Thread t2 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws InterruptedException {
                assertSame(one, e.exchange(two));
                exchanged.countDown();
                interrupted.await();
                assertSame(three, e.exchange(one));
            }});
        Thread t3 = newStartedThread(new CheckedRunnable() {
            public void realRun() throws InterruptedException {
                interrupted.await();
                assertSame(one, e.exchange(three));
            }});

        await(exchanged);
        t1.interrupt();
        awaitTermination(t1);
        interrupted.countDown();
        awaitTermination(t2);
        awaitTermination(t3);
    }

}
