/*
 * Copyright (C) 2008 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 android.test.suitebuilder;

import android.test.ClassPathPackageInfoSource;
import android.util.Log;
import com.android.internal.util.Predicate;
import junit.framework.TestCase;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Represents a collection of test classes present on the classpath. You can add individual classes
 * or entire packages. By default sub-packages are included recursively, but methods are
 * provided to allow for arbitrary inclusion or exclusion of sub-packages. Typically a
 * {@link TestGrouping} will have only one root package, but this is not a requirement.
 * 
 * {@hide} Not needed for 1.0 SDK.
 */
class TestGrouping {

    private static final String LOG_TAG = "TestGrouping";

    private final SortedSet<Class<? extends TestCase>> testCaseClasses;

    static final Comparator<Class<? extends TestCase>> SORT_BY_SIMPLE_NAME
            = new SortBySimpleName();

    static final Comparator<Class<? extends TestCase>> SORT_BY_FULLY_QUALIFIED_NAME
            = new SortByFullyQualifiedName();

    private final ClassLoader classLoader;

    TestGrouping(Comparator<Class<? extends TestCase>> comparator, ClassLoader classLoader) {
        testCaseClasses = new TreeSet<Class<? extends TestCase>>(comparator);
        this.classLoader = classLoader;
    }

    /**
     * @return A list of all tests in the package, including small, medium, large,
     *         flaky, and suppressed tests. Includes sub-packages recursively.
     */
    public List<TestMethod> getTests() {
        List<TestMethod> testMethods = new ArrayList<TestMethod>();
        for (Class<? extends TestCase> testCase : testCaseClasses) {
            for (Method testMethod : getTestMethods(testCase)) {
                testMethods.add(new TestMethod(testMethod, testCase));
            }
        }
        return testMethods;
    }

    private List<Method> getTestMethods(Class<? extends TestCase> testCaseClass) {
        List<Method> methods = Arrays.asList(testCaseClass.getMethods());
        return select(methods, new TestMethodPredicate());
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TestGrouping other = (TestGrouping) o;
        if (!this.testCaseClasses.equals(other.testCaseClasses)) {
            return false;
        }
        return this.testCaseClasses.comparator().equals(other.testCaseClasses.comparator());
    }

    public int hashCode() {
        return testCaseClasses.hashCode();
    }

    /**
     * Include all tests in the given packages and all their sub-packages, unless otherwise
     * specified. Each of the given packages must contain at least one test class, either directly
     * or in a sub-package.
     *
     * @param packageNames Names of packages to add.
     */
    void addPackagesRecursive(String... packageNames) {
        for (String packageName : packageNames) {
            List<Class<? extends TestCase>> addedClasses = testCaseClassesInPackage(packageName);
            if (addedClasses.isEmpty()) {
                Log.w(LOG_TAG, "Invalid Package: '" + packageName
                        + "' could not be found or has no tests");
            }
            testCaseClasses.addAll(addedClasses);
        }
    }

    /**
     * Exclude all tests in the given packages and all their sub-packages, unless otherwise
     * specified.
     *
     * @param packageNames Names of packages to remove.
     */
    void removePackagesRecursive(String... packageNames) {
        for (String packageName : packageNames) {
            testCaseClasses.removeAll(testCaseClassesInPackage(packageName));
        }
    }

    private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) {
        ClassPathPackageInfoSource source = ClassPathPackageInfoSource.forClassPath(classLoader);

        return selectTestClasses(source.getTopLevelClassesRecursive(packageName));
    }

    @SuppressWarnings("unchecked")
    private List<Class<? extends TestCase>> selectTestClasses(Set<Class<?>> allClasses) {
        List<Class<? extends TestCase>> testClasses = new ArrayList<Class<? extends TestCase>>();
        for (Class<?> testClass : select(allClasses,
                new TestCasePredicate())) {
            testClasses.add((Class<? extends TestCase>) testClass);
        }
        return testClasses;
    }

    private <T> List<T> select(Collection<T> items, Predicate<T> predicate) {
        ArrayList<T> selectedItems = new ArrayList<T>();
        for (T item : items) {
            if (predicate.apply(item)) {
                selectedItems.add(item);
            }
        }
        return selectedItems;
    }

    /**
     * Sort classes by their simple names (i.e. without the package prefix), using
     * their packages to sort classes with the same name.
     */
    private static class SortBySimpleName
            implements Comparator<Class<? extends TestCase>>, Serializable {

        public int compare(Class<? extends TestCase> class1,
                Class<? extends TestCase> class2) {
            int result = class1.getSimpleName().compareTo(class2.getSimpleName());
            if (result != 0) {
                return result;
            }
            return class1.getName().compareTo(class2.getName());
        }
    }

    /**
     * Sort classes by their fully qualified names (i.e. with the package
     * prefix).
     */
    private static class SortByFullyQualifiedName
            implements Comparator<Class<? extends TestCase>>, Serializable {

        public int compare(Class<? extends TestCase> class1,
                Class<? extends TestCase> class2) {
            return class1.getName().compareTo(class2.getName());
        }
    }

    private static class TestCasePredicate implements Predicate<Class<?>> {

        public boolean apply(Class aClass) {
            int modifiers = ((Class<?>) aClass).getModifiers();
            return TestCase.class.isAssignableFrom((Class<?>) aClass)
                    && Modifier.isPublic(modifiers)
                    && !Modifier.isAbstract(modifiers)
                    && hasValidConstructor((Class<?>) aClass);
        }

        @SuppressWarnings("unchecked")
        private boolean hasValidConstructor(java.lang.Class<?> aClass) {
            // The cast below is not necessary with the Java 5 compiler, but necessary with the Java 6 compiler,
            // where the return type of Class.getDeclaredConstructors() was changed
            // from Constructor<T>[] to Constructor<?>[]
            Constructor<? extends TestCase>[] constructors
                    = (Constructor<? extends TestCase>[]) aClass.getConstructors();
            for (Constructor<? extends TestCase> constructor : constructors) {
                if (Modifier.isPublic(constructor.getModifiers())) {
                    java.lang.Class[] parameterTypes = constructor.getParameterTypes();
                    if (parameterTypes.length == 0 ||
                            (parameterTypes.length == 1 && parameterTypes[0] == String.class)) {
                        return true;
                    }
                }
            }
            Log.i(LOG_TAG, String.format(
                    "TestCase class %s is missing a public constructor with no parameters " +
                    "or a single String parameter - skipping",
                    aClass.getName()));
            return false;
        }
    }

    private static class TestMethodPredicate implements Predicate<Method> {

        public boolean apply(Method method) {
            return ((method.getParameterTypes().length == 0) &&
                    (method.getName().startsWith("test")) &&
                    (method.getReturnType().getSimpleName().equals("void")));
        }
    }
}
