package org.junit.tests.running.methods;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.concurrent.TimeUnit;

import junit.framework.JUnit4TestAdapter;
import junit.framework.TestResult;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;

public class TimeoutTest {

    public static class FailureWithTimeoutTest {
        @Test(timeout = 1000)
        public void failure() {
            fail();
        }
    }

    @Test
    public void failureWithTimeout() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(FailureWithTimeoutTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        assertEquals(AssertionError.class, result.getFailures().get(0).getException().getClass());
    }

    public static class FailureWithTimeoutRunTimeExceptionTest {
        @Test(timeout = 1000)
        public void failure() {
            throw new NullPointerException();
        }
    }

    @Test
    public void failureWithTimeoutRunTimeException() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(FailureWithTimeoutRunTimeExceptionTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        assertEquals(NullPointerException.class, result.getFailures().get(0).getException().getClass());
    }

    public static class SuccessWithTimeoutTest {
        @Test(timeout = 1000)
        public void success() {
        }
    }

    @Test
    public void successWithTimeout() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(SuccessWithTimeoutTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(0, result.getFailureCount());
    }

    public static class TimeoutFailureTest {
        @Test(timeout = 100)
        public void success() throws InterruptedException {
            Thread.sleep(40000);
        }
    }

    @Ignore("was breaking gump")
    @Test
    public void timeoutFailure() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(TimeoutFailureTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        assertEquals(InterruptedException.class, result.getFailures().get(0).getException().getClass());
    }

    public static class InfiniteLoopTest {
        @Test(timeout = 100)
        public void failure() {
            infiniteLoop();
        }

        private void infiniteLoop() {
            for (; ; ) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    @Test
    public void infiniteLoop() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(InfiniteLoopTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        Throwable exception = result.getFailures().get(0).getException();
        assertTrue(exception.getMessage().contains("test timed out after 100 milliseconds"));
    }

    public static class ImpatientLoopTest {
        @Test(timeout = 1)
        public void failure() {
            infiniteLoop();
        }

        private void infiniteLoop() {
            for (; ; ) ;
        }
    }

    @Ignore("This breaks sporadically with time differences just slightly more than 200ms")
    @Test
    public void infiniteLoopRunsForApproximatelyLengthOfTimeout() throws Exception {
        // "prime the pump": running these beforehand makes the runtimes more predictable
        //                   (because of class loading?)
        JUnitCore.runClasses(InfiniteLoopTest.class, ImpatientLoopTest.class);
        long longTime = runAndTime(InfiniteLoopTest.class);
        long shortTime = runAndTime(ImpatientLoopTest.class);
        long difference = longTime - shortTime;
        assertTrue(String.format("Difference was %sms", difference), difference < 200);
    }

    private long runAndTime(Class<?> clazz) {
        JUnitCore core = new JUnitCore();
        long startTime = System.currentTimeMillis();
        core.run(clazz);
        long totalTime = System.currentTimeMillis() - startTime;
        return totalTime;
    }

    private String stackForException(Throwable exception) {
        Writer buffer = new StringWriter();
        PrintWriter writer = new PrintWriter(buffer);
        exception.printStackTrace(writer);
        return buffer.toString();
    }
    
    @Test
    public void stalledThreadAppearsInStackTrace() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(InfiniteLoopTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        Throwable exception = result.getFailures().get(0).getException();
        assertThat(stackForException(exception), containsString("infiniteLoop")); // Make sure we have the stalled frame on the stack somewhere
    }

    public static class InfiniteLoopMultithreaded {
        
        private static class ThreadTest implements Runnable {
            private boolean fStall;

            public ThreadTest(boolean stall) {
                fStall = stall;
            }

            public void run() {
                if (fStall)
                    for (; ; ) ;   
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
            }
        }
        
        public void failure(boolean mainThreadStalls) throws Exception {
            Thread t1 = new Thread(new ThreadTest(false), "timeout-thr1");
            Thread t2 = new Thread(new ThreadTest(!mainThreadStalls), "timeout-thr2");
            Thread t3 = new Thread(new ThreadTest(false), "timeout-thr3");
            t1.start();
            t2.start();
            t3.start();
            if (mainThreadStalls)
                for (; ; ) ;
            t1.join();
            t2.join();
            t3.join();
        }
   }
    
    public static class InfiniteLoopWithStuckThreadTest {
        @Rule
        public TestRule globalTimeout = Timeout.builder()
            .withTimeout(100, TimeUnit.MILLISECONDS)
            .withLookingForStuckThread(true)
            .build();

        @Test
        public void failure() throws Exception {
            (new InfiniteLoopMultithreaded()).failure(false);
        }
    }
    
    public static class InfiniteLoopStuckInMainThreadTest {
        @Rule
        public TestRule globalTimeout = Timeout.builder()
            .withTimeout(100, TimeUnit.MILLISECONDS)
            .withLookingForStuckThread(true)
            .build();

        @Test
        public void failure() throws Exception {
            (new InfiniteLoopMultithreaded()).failure(true);
        }
    }

    @Test
    public void timeoutFailureMultithreaded() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(InfiniteLoopWithStuckThreadTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(2, result.getFailureCount());
        Throwable exception[] = new Throwable[2];
        for (int i = 0; i < 2; i++)
            exception[i] = result.getFailures().get(i).getException();
        assertThat(exception[0].getMessage(), containsString("test timed out after 100 milliseconds"));
        assertThat(stackForException(exception[0]), containsString("Thread.join"));
        assertThat(exception[1].getMessage(), containsString("Appears to be stuck in thread timeout-thr2"));
    }

    @Test
    public void timeoutFailureMultithreadedStuckInMain() throws Exception {
        JUnitCore core = new JUnitCore();
        Result result = core.run(InfiniteLoopStuckInMainThreadTest.class);
        assertEquals(1, result.getRunCount());
        assertEquals(1, result.getFailureCount());
        Throwable exception = result.getFailures().get(0).getException();
        assertThat(exception.getMessage(), containsString("test timed out after 100 milliseconds"));
        assertThat(exception.getMessage(), not(containsString("Appears to be stuck")));
    }

    @Test
    public void compatibility() {
        TestResult result = new TestResult();
        new JUnit4TestAdapter(InfiniteLoopTest.class).run(result);
        assertEquals(1, result.errorCount());
    }

    public static class WillTimeOut {
        static boolean afterWasCalled = false;

        @Test(timeout = 1)
        public void test() {
            for (; ; ) {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    // ok, tests are over
                }
            }
        }

        @After
        public void after() {
            afterWasCalled = true;
        }
    }

    @Test
    public void makeSureAfterIsCalledAfterATimeout() {
        JUnitCore.runClasses(WillTimeOut.class);
        assertThat(WillTimeOut.afterWasCalled, is(true));
    }

    public static class TimeOutZero {
        @Rule
        public Timeout timeout = Timeout.seconds(0);

        @Test
        public void test() {
            try {
                Thread.sleep(200); // long enough to suspend thread execution
            } catch (InterruptedException e) {
                // Don't care
            }
        }
    }

    @Test
    public void testZeroTimeoutIsIgnored() {
        JUnitCore core = new JUnitCore();
        Result result = core.run(TimeOutZero.class);
        assertEquals("Should run the test", 1, result.getRunCount());
        assertEquals("Test should not have failed", 0, result.getFailureCount());
    }

    private static class TimeoutSubclass extends Timeout {

        public TimeoutSubclass(long timeout, TimeUnit timeUnit) {
            super(timeout, timeUnit);
        }

        public long getTimeoutFromSuperclass(TimeUnit unit) {
            return super.getTimeout(unit);
        }
    }

    public static class TimeOutOneSecond {
        @Rule
        public TimeoutSubclass timeout = new TimeoutSubclass(1, TimeUnit.SECONDS);

        @Test
        public void test() {
            assertEquals(1000, timeout.getTimeoutFromSuperclass(TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testGetTimeout() {
        JUnitCore core = new JUnitCore();
        Result result = core.run(TimeOutOneSecond.class);
        assertEquals("Should run the test", 1, result.getRunCount());
        assertEquals("Test should not have failed", 0, result.getFailureCount());
    }
}
