package org.junit.tests.experimental.max;

import static org.hamcrest.CoreMatchers.containsString;
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.File;
import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.max.MaxCore;
import org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.runner.Computer;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.tests.AllTests;

public class MaxStarterTest {
    private MaxCore fMax;

    private File fMaxFile;

    @Before
    public void createMax() {
        fMaxFile = new File("MaxCore.ser");
        if (fMaxFile.exists()) {
            fMaxFile.delete();
        }
        fMax = MaxCore.storedLocally(fMaxFile);
    }

    @After
    public void forgetMax() {
        fMaxFile.delete();
    }

    public static class TwoTests {
        @Test
        public void succeed() {
        }

        @Test
        public void dontSucceed() {
            fail();
        }
    }

    @Test
    public void twoTestsNotRunComeBackInRandomOrder() {
        Request request = Request.aClass(TwoTests.class);
        List<Description> things = fMax.sortedLeavesForTest(request);
        Description succeed = Description.createTestDescription(TwoTests.class,
                "succeed");
        Description dontSucceed = Description.createTestDescription(
                TwoTests.class, "dontSucceed");
        assertTrue(things.contains(succeed));
        assertTrue(things.contains(dontSucceed));
        assertEquals(2, things.size());
    }

    @Test
    public void preferNewTests() {
        Request one = Request.method(TwoTests.class, "succeed");
        fMax.run(one);
        Request two = Request.aClass(TwoTests.class);
        List<Description> things = fMax.sortedLeavesForTest(two);
        Description dontSucceed = Description.createTestDescription(
                TwoTests.class, "dontSucceed");
        assertEquals(dontSucceed, things.get(0));
        assertEquals(2, things.size());
    }

    // This covers a seemingly-unlikely case, where you had a test that failed
    // on the
    // last run and you also introduced new tests. In such a case it pretty much
    // doesn't matter
    // which order they run, you just want them both to be early in the sequence
    @Test
    public void preferNewTestsOverTestsThatFailed() {
        Request one = Request.method(TwoTests.class, "dontSucceed");
        fMax.run(one);
        Request two = Request.aClass(TwoTests.class);
        List<Description> things = fMax.sortedLeavesForTest(two);
        Description succeed = Description.createTestDescription(TwoTests.class,
                "succeed");
        assertEquals(succeed, things.get(0));
        assertEquals(2, things.size());
    }

    @Test
    public void preferRecentlyFailed() {
        Request request = Request.aClass(TwoTests.class);
        fMax.run(request);
        List<Description> tests = fMax.sortedLeavesForTest(request);
        Description dontSucceed = Description.createTestDescription(
                TwoTests.class, "dontSucceed");
        assertEquals(dontSucceed, tests.get(0));
    }

    @Test
    public void sortTestsInMultipleClasses() {
        Request request = Request.classes(Computer.serial(), TwoTests.class,
                TwoTests.class);
        fMax.run(request);
        List<Description> tests = fMax.sortedLeavesForTest(request);
        Description dontSucceed = Description.createTestDescription(
                TwoTests.class, "dontSucceed");
        assertEquals(dontSucceed, tests.get(0));
        assertEquals(dontSucceed, tests.get(1));
    }

    public static class TwoUnEqualTests {
        @Test
        public void slow() throws InterruptedException {
            Thread.sleep(100);
            fail();
        }

        @Test
        public void fast() {
            fail();
        }

    }

    @Test
    public void rememberOldRuns() {
        fMax.run(TwoUnEqualTests.class);

        MaxCore reincarnation = MaxCore.storedLocally(fMaxFile);
        List<Failure> failures = reincarnation.run(TwoUnEqualTests.class)
                .getFailures();
        assertEquals("fast", failures.get(0).getDescription().getMethodName());
        assertEquals("slow", failures.get(1).getDescription().getMethodName());
    }

    @Test
    public void preferFast() {
        Request request = Request.aClass(TwoUnEqualTests.class);
        fMax.run(request);
        Description thing = fMax.sortedLeavesForTest(request).get(1);
        assertEquals(Description.createTestDescription(TwoUnEqualTests.class,
                "slow"), thing);
    }

    @Test
    public void listenersAreCalledCorrectlyInTheFaceOfFailures()
            throws Exception {
        JUnitCore core = new JUnitCore();
        final List<Failure> failures = new ArrayList<Failure>();
        core.addListener(new RunListener() {
            @Override
            public void testRunFinished(Result result) throws Exception {
                failures.addAll(result.getFailures());
            }
        });
        fMax.run(Request.aClass(TwoTests.class), core);
        assertEquals(1, failures.size());
    }

    @Test
    public void testsAreOnlyIncludedOnceWhenExpandingForSorting()
            throws Exception {
        Result result = fMax.run(Request.aClass(TwoTests.class));
        assertEquals(2, result.getRunCount());
    }

    public static class TwoOldTests extends TestCase {
        public void testOne() {
        }

        public void testTwo() {
        }
    }

    @Test
    public void junit3TestsAreRunOnce() throws Exception {
        Result result = fMax.run(Request.aClass(TwoOldTests.class),
                new JUnitCore());
        assertEquals(2, result.getRunCount());
    }

    @Test
    public void filterSingleMethodFromOldTestClass() throws Exception {
        final Description method = Description.createTestDescription(
                TwoOldTests.class, "testOne");
        Filter filter = Filter.matchMethodDescription(method);
        JUnit38ClassRunner child = new JUnit38ClassRunner(TwoOldTests.class);
        child.filter(filter);
        assertEquals(1, child.testCount());
    }

    @Test
    public void testCountsStandUpToFiltration() {
        assertFilterLeavesTestUnscathed(AllTests.class);
    }

    private void assertFilterLeavesTestUnscathed(Class<?> testClass) {
        Request oneClass = Request.aClass(testClass);
        Request filtered = oneClass.filterWith(new Filter() {
            @Override
            public boolean shouldRun(Description description) {
                return true;
            }

            @Override
            public String describe() {
                return "Everything";
            }
        });

        int filterCount = filtered.getRunner().testCount();
        int coreCount = oneClass.getRunner().testCount();
        assertEquals("Counts match up in " + testClass, coreCount, filterCount);
    }

    private static class MalformedJUnit38Test {
        private MalformedJUnit38Test() {
        }

        @SuppressWarnings("unused")
        public void testSucceeds() {
        }
    }

    @Test
    public void maxShouldSkipMalformedJUnit38Classes() {
        Request request = Request.aClass(MalformedJUnit38Test.class);
        fMax.run(request);
    }

    public static class MalformedJUnit38TestMethod extends TestCase {
        @SuppressWarnings("unused")
        private void testNothing() {
        }
    }

    @Test
    public void correctErrorFromMalformedTest() {
        Request request = Request.aClass(MalformedJUnit38TestMethod.class);
        JUnitCore core = new JUnitCore();
        Request sorted = fMax.sortRequest(request);
        Runner runner = sorted.getRunner();
        Result result = core.run(runner);
        Failure failure = result.getFailures().get(0);
        assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod"));
        assertThat(failure.toString(), containsString("testNothing"));
        assertThat(failure.toString(), containsString("isn't public"));
    }

    public static class HalfMalformedJUnit38TestMethod extends TestCase {
        public void testSomething() {
        }

        @SuppressWarnings("unused")
        private void testNothing() {
        }
    }

    @Test
    public void halfMalformed() {
        assertThat(JUnitCore.runClasses(HalfMalformedJUnit38TestMethod.class)
                .getFailureCount(), is(1));
    }


    @Test
    public void correctErrorFromHalfMalformedTest() {
        Request request = Request.aClass(HalfMalformedJUnit38TestMethod.class);
        JUnitCore core = new JUnitCore();
        Request sorted = fMax.sortRequest(request);
        Runner runner = sorted.getRunner();
        Result result = core.run(runner);
        Failure failure = result.getFailures().get(0);
        assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod"));
        assertThat(failure.toString(), containsString("testNothing"));
        assertThat(failure.toString(), containsString("isn't public"));
    }
}
