/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.ant.antunit.junit4;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.ant.antunit.AntUnitExecutionNotifier;
import org.apache.ant.antunit.AssertionFailedException;
import org.apache.ant.antunit.junit3.AntUnitSuite;
import org.apache.ant.antunit.junit3.AntUnitTestCase;
import org.junit.internal.runners.InitializationError;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.manipulation.Sortable;
import org.junit.runner.manipulation.Sorter;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;

/**
 * JUnit4 Runner to put in a RunWith annotation of the AntUnitSuite when using a
 * JUnit4 runner. Using this runner is not mandatory because junit4 is able to
 * run junit3 test. However, the test may be faster with this Runner (with the
 * default junit4 adapter, the suiteSetUp and suiteTearDown will be executed
 * around every test target). Also, more features are available when this runner
 * is used (filtering & sorting)
 */
public class AntUnitSuiteRunner extends Runner implements Filterable, Sortable {

    private final AntUnitSuite junit3Suite;
    private final Map/*<String, Description>*/ targetDescriptions = new HashMap();
    private final List/*<String>*/ targetsOrder = new LinkedList();
    
    private AntUnitSuiteRunner(AntUnitSuite suite, Class junitTestClass) {
        junit3Suite = suite;
        Enumeration tests = suite.tests();
        while (tests.hasMoreElements()) {
            //TODO Handle the the case of FileNotFound. 
            //In that case the suite contains an error Test and we have
            //a ClassCastException instead of a nice & clear error
            //TODO Handle the possibility for the user to define suite of AntUnit scripts
            AntUnitTestCase tc = (AntUnitTestCase) tests.nextElement();
            Description tc_desc = Description.createTestDescription(junitTestClass, tc.getName());
            targetDescriptions.put(tc.getTarget(), tc_desc);
            targetsOrder.add(tc.getTarget());
        }
    }

    public AntUnitSuiteRunner(Class testCaseClass) throws InitializationError {
        this(getJUnit3AntSuite(testCaseClass), testCaseClass);
    }

    private static AntUnitSuite getJUnit3AntSuite(Class testCaseClass)
            throws InitializationError {
        try {
            Method suiteMethod = testCaseClass.getMethod("suite", new Class[0]);
            if (!Modifier.isStatic(suiteMethod.getModifiers())) {
                throw new InitializationError("suite method must be static");
            }
            Object suite = suiteMethod.invoke(null, new Object[0]);
            if (suite == null) {
                throw new InitializationError("suite method can not return null");
            }
            if (!(suite instanceof AntUnitSuite)) {
                throw new InitializationError("suite method must return an AntUnitSuite");
            }
            return (AntUnitSuite) suite;
        } catch (NoSuchMethodException e) {
            throw new InitializationError(new Throwable[] { e });
        } catch (IllegalAccessException e) {
            throw new InitializationError(new Throwable[] { e });
        } catch (InvocationTargetException e) {
            throw new InitializationError(new Throwable[] { e });
        }
    }

    /**
     * @Overwrite Filterable implementation
     */
    public void filter(Filter filter) throws NoTestsRemainException {
        for (Iterator iter= targetDescriptions.entrySet().iterator(); iter.hasNext();) {
            Map.Entry mapEntry = (Entry) iter.next(); 
            if (!filter.shouldRun((Description) mapEntry.getValue()))
                iter.remove();
                targetsOrder.remove(mapEntry.getKey());
        }
    }

    /**
     * @Overwrite Sortable implementation
     */
    public void sort(final Sorter sorter) {
        Collections.sort(targetsOrder, new Comparator/*<String>*/() {
            public int compare(Object target1, Object target2) {
                Description d2 = (Description)targetDescriptions.get(target2);
                Description d1 = (Description)targetDescriptions.get(target1);
                return sorter.compare(d1, d2);
            }
        });
        /*for (Runner each : fRunners)
            sorter.apply(each);
        */
    }

    /**
     * @Overwrite Runner implementation
     */
    public Description getDescription() {
        Description r = Description.createSuiteDescription(
                junit3Suite.getName(), new Annotation[0]);
        
        Collection childDesc = targetDescriptions.values();
        for (Iterator iterator = childDesc.iterator(); iterator.hasNext();) {
            Description desc = (Description) iterator.next();
            r.addChild(desc);
        }
        return r;
    }

    /**
     * @Overwrite Runner implementation
     */
    public void run(final RunNotifier junitNotifier) {
        LinkedList targetList = new LinkedList(targetDescriptions.keySet());
        
        AntUnitExecutionNotifier antUnitNotifier = new AntUnitExecutionNotifier() {            
            public void fireStartTest(String targetName) {
                junitNotifier.fireTestStarted(getDescription(targetName));
            }
            public void fireEndTest(String targetName) {
                junitNotifier.fireTestFinished(getDescription(targetName));                
            }
            public void fireError(String targetName, Throwable t) {
                Failure failure = new Failure(getDescription(targetName), t);
                junitNotifier.fireTestFailure(failure);
            }
            public void fireFail(String targetName, AssertionFailedException ae) {
                Failure failure = new Failure(getDescription(targetName), ae);
                junitNotifier.fireTestFailure(failure);
            }            
            private Description getDescription(String targetName) {
                return (Description) targetDescriptions.get(targetName);
            }
        };
        
        junit3Suite.runInContainer(targetList, antUnitNotifier);
    }

}
