/*
 * 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(ExchangerTest.class);
    // }

    /**
     * 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);
    }

}
