/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package vogar.target.junit;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import vogar.ClassAnalyzer;

/**
 * Utilities for manipulating JUnit tests.
 */
public final class Junit3 {
    private Junit3() {}

    private static final Method setUp;
    private static final Method tearDown;
    private static final Method runTest;
    static {
        try {
            setUp = TestCase.class.getDeclaredMethod("setUp");
            setUp.setAccessible(true);
            tearDown = TestCase.class.getDeclaredMethod("tearDown");
            tearDown.setAccessible(true);
            runTest = TestCase.class.getDeclaredMethod("runTest");
            runTest.setAccessible(true);
        } catch (NoSuchMethodException e) {
            throw new AssertionError();
        }
    }

    /**
     * Creates eager JUnit Test instances from the given test case or test
     * suite.
     */
    public static List<Test> classToJunitTests(Class<?> testClass) {
        try {
            try {
                Method suiteMethod = testClass.getMethod("suite");
                return Collections.singletonList((Test) suiteMethod.invoke(null));
            } catch (NoSuchMethodException ignored) {
            }

            if (TestCase.class.isAssignableFrom(testClass)) {
                List<Test> result = new ArrayList<Test>();
                for (Method m : testClass.getMethods()) {
                    if (!m.getName().startsWith("test")) {
                        continue;
                    }
                    if (m.getParameterTypes().length == 0) {
                        TestCase testCase = (TestCase) testClass.newInstance();
                        testCase.setMethod(m);
                        result.add(testCase);
                    } else {
                        // TODO: warn
                    }
                }
                return result;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        throw new IllegalArgumentException("Unknown test class: " + testClass);
    }

    /**
     * Creates lazy vogar test instances from the given test case or test
     * suite.
     *
     * @param methodNames if non-empty, this is the list of test method names.
     */
    static List<VogarTest> classToVogarTests(Class<?> testClass, Collection<String> methodNames) {
        List<VogarTest> result = new ArrayList<VogarTest>();
        getSuiteMethods(result, testClass, methodNames);
        return result;
    }

    public static boolean isJunit3Test(Class<?> klass) {
        // public class FooTest extends TestCase {...}
        //   or
        // public class FooSuite {
        //    public static Test suite() {...}
        // }
        return (TestCase.class.isAssignableFrom(klass) && !Modifier.isAbstract(klass.getModifiers()))
                || new ClassAnalyzer(klass).hasMethod(true, Test.class, "suite");
    }

    private static void getSuiteMethods(
        List<VogarTest> out, Class<?> testClass, Collection<String> methodNames) {
        /*
         * Handle classes assignable to TestCase
         */
        if (TestCase.class.isAssignableFrom(testClass)) {
            @SuppressWarnings("unchecked")
            Class<? extends TestCase> testCaseClass = (Class<? extends TestCase>) testClass;

            if (methodNames.isEmpty()) {
                for (Method m : testClass.getMethods()) {
                    if (!m.getName().startsWith("test")) {
                        continue;
                    }
                    if (m.getParameterTypes().length == 0) {
                        out.add(TestMethod.create(testCaseClass, m));
                    } else {
                        // TODO: warn
                    }
                }
            } else {
                for (String methodName : methodNames) {
                    try {
                        out.add(TestMethod.create(testCaseClass, testClass.getMethod(methodName)));
                    } catch (final NoSuchMethodException e) {
                        AssertionFailedError cause = new AssertionFailedError(
                                "Method \"" + methodName + "\" not found");
                        ConfigurationError error = new ConfigurationError(
                                testClass.getName() + "#" + methodName,
                                cause);
                        out.add(error);
                    }
                }
            }

            return;
        }

        /*
         * Handle classes that define suite()
         */
        try {
            Method suiteMethod = testClass.getMethod("suite");
            junit.framework.Test test;
            try {
                test = (junit.framework.Test) suiteMethod.invoke(null);
            } catch (InvocationTargetException e) {
                out.add(new ConfigurationError(testClass.getName() + "#suite", e.getCause()));
                return;
            } catch (Throwable e) {
                out.add(new ConfigurationError(testClass.getName() + "#suite", e));
                return;
            }

            if (test instanceof TestCase) {
                getTestCaseTest(out, (TestCase) test, methodNames);
            } else if (test instanceof TestSuite) {
                getTestSuiteTests(out, (TestSuite) test, methodNames);
            } else {
                out.add(new ConfigurationError(testClass.getName() + "#suite",
                        new IllegalStateException("Unknown suite() result: " + test)));
            }
            return;
        } catch (NoSuchMethodException ignored) {
        }

        out.add(new ConfigurationError(testClass.getName() + "#suite",
                new IllegalStateException("Not a test case: " + testClass)));
    }

    private static void getTestSuiteTests(List<VogarTest> out, TestSuite suite,
            Collection<String> methodNames) {
      for (Object testsOrSuite : getTestsAndSuites(suite)) {
          if (testsOrSuite instanceof Class) {
              getSuiteMethods(out, (Class<?>) testsOrSuite, methodNames);
          } else if (testsOrSuite instanceof TestCase) {
              getTestCaseTest(out, (TestCase) testsOrSuite, methodNames);
          } else if (testsOrSuite instanceof TestSuite) {
              getTestSuiteTests(out, (TestSuite) testsOrSuite, methodNames);
          } else if (testsOrSuite != null) {
              out.add(new ConfigurationError(testsOrSuite.getClass().getName() + "#getClass",
                      new IllegalStateException("Unknown test: " + testsOrSuite)));
          }
      }
    }

    private static List<Object> getTestsAndSuites(TestSuite suite) {
        try {
            return suite.getTestsAndSuites();
        } catch (NoSuchMethodError e) {
            // This is running with the standard JUnit TestSuite class and not the Vogar specific
            // one so the getTestsAndSuites() method is not available. Fall back to using the
            // tests() method.
            if (!e.getMessage().contains("getTestsAndSuites()Ljava/util/List;")) {
                throw e;
            }

            // Create a list from the enumeration, cannot use Collections.list() without a lot of
            // ugly casting.
            Enumeration<?> enumeration = suite.tests();
            List<Object> tests = new ArrayList<Object>();
            while (enumeration.hasMoreElements()) {
                tests.add(enumeration.nextElement());
            }
            return tests;
        }
    }


    private static void getTestCaseTest(List<VogarTest> out, TestCase testCase,
            Collection<String> methodNames) {
        if (methodNames.isEmpty() || methodNames.contains(testCase.getName())) {
            try {
                out.add(new TestCaseInstance(testCase, testCase.getMethod()));
            } catch (NoSuchMethodError e) {
                if (!e.getMessage().contains("getMethod()Ljava/lang/reflect/Method;")) {
                    throw e;
                }

                out.add(new TestCaseInstance(testCase, runTest));
            }
        }
    }

    private abstract static class VogarJUnitTest implements VogarTest {
        protected final Class<? extends TestCase> testClass;
        protected final Method method;

        protected VogarJUnitTest(Class<? extends TestCase> testClass, Method method) {
            this.testClass = testClass;
            this.method = method;
        }

        public void run() throws Throwable {
            TestCase testCase;
            try {
                testCase = getTestCase();
            } catch (InvocationTargetException t) {
                throw t.getCause();
            }
            Throwable failure = null;
            try {
                setUp.invoke(testCase);
                method.invoke(testCase);
            } catch (InvocationTargetException t) {
                failure = t.getCause();
            } catch (Throwable t) {
                failure = t;
            }

            try {
                tearDown.invoke(testCase);
            } catch (InvocationTargetException t) {
                if (failure == null) {
                    failure = t.getCause();
                }
            } catch (Throwable t) {
                if (failure == null) {
                    failure = t;
                }
            }

            if (failure != null) {
                throw failure;
            }
        }

        protected abstract TestCase getTestCase() throws Exception;
    }

    /**
     * A JUnit TestCase constructed on demand and then released.
     */
    private static class TestMethod extends VogarJUnitTest {
        private final Constructor<? extends TestCase> constructor;
        private final Object[] constructorArgs;

        private TestMethod(Class<? extends TestCase> testClass, Method method,
                Constructor<? extends TestCase> constructor, Object[] constructorArgs) {
            super(testClass, method);
            this.constructor = constructor;
            this.constructorArgs = constructorArgs;
        }

        public static VogarTest create(Class<? extends TestCase> testClass, Method method) {
            try {
                return new TestMethod(testClass, method, testClass.getConstructor(), new Object[0]);
            } catch (NoSuchMethodException ignored) {
            }
            try {
                return new TestMethod(testClass, method, testClass.getConstructor(String.class),
                        new Object[] { method.getName() });
            } catch (NoSuchMethodException ignored) {
            }
            String testClassName = testClass.getName();
            return new ConfigurationError(testClassName + "#" + method.getName(),
                    new AssertionFailedError("Class " + testClassName
                            + " has no public constructor TestCase(String name) or TestCase()"));
        }

        @Override protected TestCase getTestCase() throws Exception {

            if (!Modifier.isPublic(constructor.getDeclaringClass().getModifiers())) {
                throw new AssertionFailedError("Class " + testClass.getName() + " is not public");
            }

            TestCase testCase = constructor.newInstance(constructorArgs);
            // If the test case used the no argument constructor then make sure to set its name
            // correctly.
            if (constructor.getParameterTypes().length == 0) {
                testCase.setName(method.getName());
            }
            return testCase;
        }

        @Override public String toString() {
            return testClass.getName() + "#" + method.getName();
        }
    }

    /**
     * A JUnit TestCase already constructed.
     */
    private static class TestCaseInstance extends VogarJUnitTest {
        private final TestCase testCase;

        private TestCaseInstance(TestCase testCase, Method method) {
            super(testCase.getClass(), method);
            this.testCase = testCase;
        }

        @Override protected TestCase getTestCase() throws Exception {
            return testCase;
        }

        @Override public String toString() {
            return testCase.getClass().getName() + "#" + testCase.getName();
        }
    }
}
