/*
 *  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.tools.ant.taskdefs.optional.junit;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper;

/**
 * Run a single JUnit test.
 *
 * <p>The JUnit test is actually run by {@link JUnitTestRunner}.
 * So read the doc comments for that class :)</p>
 *
 * @since Ant 1.2
 *
 * @see JUnitTask
 * @see JUnitTestRunner
 */
public class JUnitTest extends BaseTest implements Cloneable {

    /** the name of the test case */
    private String name = null;

    /**
     * whether the list of test methods has been specified
     * @see #setMethods(java.lang.String)
     * @see #setMethods(java.lang.String[])
     */
    private boolean methodsSpecified = false;

    /** comma-separated list of names of test methods to execute */
    private String methodsList = null;

    /** the names of test methods to execute */
    private String[] methods = null;

    /** the name of the result file */
    private String outfile = null;

    // @todo this is duplicating TestResult information. Only the time is not
    // part of the result. So we'd better derive a new class from TestResult
    // and deal with it. (SB)
    private long runs, failures, errors;
    /**
    @since Ant 1.9.0
    */
    private long skips;

    private long runTime;

    private int antThreadID;

    // Snapshot of the system properties
    private Properties props = null;

    /** No arg constructor. */
    public JUnitTest() {
    }

    /**
     * Constructor with name.
     * @param name the name of the test.
     */
    public JUnitTest(String name) {
        this.name  = name;
    }

    /**
     * Constructor with options.
     * @param name the name of the test.
     * @param haltOnError if true halt the tests if there is an error.
     * @param haltOnFailure if true halt the tests if there is a failure.
     * @param filtertrace if true filter stack traces.
     */
    public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
            boolean filtertrace) {
        this(name, haltOnError, haltOnFailure, filtertrace, null, 0);
    }

    /**
     * Constructor with options.
     * @param name the name of the test.
     * @param haltOnError if true halt the tests if there is an error.
     * @param haltOnFailure if true halt the tests if there is a failure.
     * @param filtertrace if true filter stack traces.
     * @param methods if non-null run only these test methods
     * @since 1.8.2
     */
    public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
                     boolean filtertrace, String[] methods) {
        this(name, haltOnError, haltOnFailure, filtertrace, methods, 0);
    }

    /**
     * Constructor with options.
     * @param name the name of the test.
     * @param haltOnError if true halt the tests if there is an error.
     * @param haltOnFailure if true halt the tests if there is a failure.
     * @param filtertrace if true filter stack traces.
     * @param methods if non-null run only these test methods
     * @param thread Ant thread ID in which test is currently running
     * @since 1.9.4
     */
    public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
                     boolean filtertrace, String[] methods, int thread) {
        this.name  = name;
        this.haltOnError = haltOnError;
        this.haltOnFail = haltOnFailure;
        this.filtertrace = filtertrace;
        this.methodsSpecified = methods != null;
        this.methods = methodsSpecified ? (String[]) methods.clone() : null;
        this.antThreadID = thread;
    }

    /**
     * Sets names of individual test methods to be executed.
     * @param value comma-separated list of names of individual test methods
     *              to be executed,
     *              or <code>null</code> if all test methods should be executed
     * @since 1.8.2
     */
    public void setMethods(String value) {
        methodsList = value;
        methodsSpecified = (value != null);
        methods = null;
    }

    /**
     * Sets names of individual test methods to be executed.
     * @param value non-empty array of names of test methods to be executed
     * @see #setMethods(String)
     * @since 1.8.2
     */
    void setMethods(String[] value) {
        methods = value;
        methodsSpecified = (value != null);
        methodsList = null;
    }

    /**
     * Set the name of the test class.
     * @param value the name to use.
     */
    public void setName(String value) {
        name = value;
    }

    /**
     * Set the thread id
     * @param thread the Ant id of the thread running this test
     * (this is not the system process or thread id)
     * (this will be 0 in single-threaded mode).
     * @since Ant 1.9.4
     */
    public void setThread(int thread) {
        this.antThreadID = thread;
    }

    /**
     * Set the name of the output file.
     * @param value the name of the output file to use.
     */
    public void setOutfile(String value) {
        outfile = value;
    }

    /**
     * Informs whether a list of test methods has been specified in this test.
     * @return <code>true</code> if test methods to be executed have been
     *         specified, <code>false</code> otherwise
     * @see #setMethods(java.lang.String)
     * @see #setMethods(java.lang.String[])
     * @since 1.8.2
     */
    boolean hasMethodsSpecified() {
        return methodsSpecified;
    }

    /**
     * Get names of individual test methods to be executed.
     *
     * @return array of names of the individual test methods to be executed,
     *         or <code>null</code> if all test methods in the suite
     *         defined by the test class will be executed
     * @since 1.8.2
     */
    String[] getMethods() {
        if (methodsSpecified && (methods == null)) {
            resolveMethods();
        }
        return methods;
    }

    /**
     * Gets a comma-separated list of names of methods that are to be executed
     * by this test.
     * @return the comma-separated list of test method names, or an empty
     *         string of no method is to be executed, or <code>null</code>
     *         if no method is specified
     * @since 1.8.2
     */
    String getMethodsString() {
        if ((methodsList == null) && methodsSpecified) {
            if (methods.length == 0) {
                methodsList = "";
            } else if (methods.length == 1) {
                methodsList = methods[0];
            } else {
                StringBuffer buf = new StringBuffer(methods.length * 16);
                buf.append(methods[0]);
                for (int i = 1; i < methods.length; i++) {
                    buf.append(',').append(methods[i]);
                }
                methodsList = buf.toString();
            }
        }
        return methodsList;
    }

    /**
     * Computes the value of the {@link #methods} field from the value
     * of the {@link #methodsList} field, if it has not been computed yet.
     * @exception BuildException if the value of the {@link #methodsList} field
     *                           was invalid
     * @since 1.8.2
     */
    void resolveMethods() {
        if ((methods == null) && methodsSpecified) {
            try {
                methods = parseTestMethodNamesList(methodsList);
            } catch (IllegalArgumentException ex) {
                throw new BuildException(
                        "Invalid specification of test methods: \""
                            + methodsList
                            + "\"; expected: comma-separated list of valid Java identifiers",
                        ex);
            }
        }
    }

    /**
     * Parses a comma-separated list of method names and check their validity.
     * @param methodNames comma-separated list of method names to be parsed
     * @return array of individual test method names
     * @exception  java.lang.IllegalArgumentException
     *             if the given string is <code>null</code> or if it is not
     *             a comma-separated list of valid Java identifiers;
     *             an empty string is acceptable and is handled as an empty
     *             list
     * @since 1.8.2
     */
    public static String[] parseTestMethodNamesList(String methodNames)
                                            throws IllegalArgumentException {
        if (methodNames == null) {
            throw new IllegalArgumentException("methodNames is <null>");
        }

        methodNames = methodNames.trim();

        int length = methodNames.length();
        if (length == 0) {
            return new String[0];
        }

        /* strip the trailing comma, if any */
        if (methodNames.charAt(length - 1) == ',') {
            methodNames = methodNames.substring(0, length - 1).trim();
            length = methodNames.length();
            if (length == 0) {
                throw new IllegalArgumentException("Empty method name");
            }
        }

        final char[] chars = methodNames.toCharArray();
        /* easy detection of one particular case of illegal string: */
        if (chars[0] == ',') {
            throw new IllegalArgumentException("Empty method name");
        }
        /* count number of method names: */
        int wordCount = 1;
        for (int i = 1; i < chars.length; i++) {
            if (chars[i] == ',') {
                wordCount++;
            }
        }
        /* prepare the resulting array: */
        String[] result = new String[wordCount];
        /* parse the string: */
        final int stateBeforeWord = 1;
        final int stateInsideWord = 2;
        final int stateAfterWord = 3;
        //
        int state = stateBeforeWord;
        int wordStartIndex = -1;
        int wordIndex = 0;
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            switch (state) {
                case stateBeforeWord:
                    if (c == ',') {
                        throw new IllegalArgumentException("Empty method name");
                    } else if (c == ' ') {
                        // remain in the same state
                    } else if (Character.isJavaIdentifierStart(c)) {
                        wordStartIndex = i;
                        state = stateInsideWord;
                    } else {
                        throw new IllegalArgumentException("Illegal start of method name: " + c);
                    }
                    break;
                case stateInsideWord:
                    if (c == ',') {
                        result[wordIndex++] = methodNames.substring(wordStartIndex, i);
                        state = stateBeforeWord;
                    } else if (c == ' ') {
                        result[wordIndex++] = methodNames.substring(wordStartIndex, i);
                        state = stateAfterWord;
                    } else if (Character.isJavaIdentifierPart(c)) {
                        // remain in the same state
                    } else {
                        throw new IllegalArgumentException("Illegal character in method name: " + c);
                    }
                    break;
                case stateAfterWord:
                    if (c == ',') {
                        state = stateBeforeWord;
                    } else if (c == ' ') {
                        // remain in the same state
                    } else {
                        throw new IllegalArgumentException("Space in method name");
                    }
                    break;
                default:
                    // this should never happen
            }
        }
        switch (state) {
            case stateBeforeWord:
            case stateAfterWord:
                break;
            case stateInsideWord:
                result[wordIndex++] = methodNames.substring(wordStartIndex, chars.length);
                break;
            default:
                // this should never happen
        }
        return result;
    }

    /**
     * Get the name of the test class.
     * @return the name of the test.
     */
    public String getName() {
        return name;
    }

    /**
     * Get the Ant id of the thread running the test.
     * @return the thread id
     */
    public int getThread() {
        return antThreadID;
    }

    /**
     * Get the name of the output file
     *
     * @return the name of the output file.
     */
    public String getOutfile() {
        return outfile;
    }

    /**
     * Set the number of runs, failures, errors, and skipped tests.
     * @param runs     the number of runs.
     * @param failures the number of failures.
     * @param errors   the number of errors.
     * Kept for backward compatibility with Ant 1.8.4
     */
    public void setCounts(long runs, long failures, long errors) {
        this.runs = runs;
        this.failures = failures;
        this.errors = errors;
    }
    /**
     * Set the number of runs, failures, errors, and skipped tests.
     * @param runs     the number of runs.
     * @param failures the number of failures.
     * @param errors   the number of errors.
     * @param skips   the number of skipped tests.
     * @since Ant 1.9.0
     */
    public void setCounts(long runs, long failures, long errors, long skips) {
        this.runs = runs;
        this.failures = failures;
        this.errors = errors;
        this.skips = skips;
    }

    /**
     * Set the runtime.
     * @param runTime the time in milliseconds.
     */
    public void setRunTime(long runTime) {
        this.runTime = runTime;
    }

    /**
     * Get the number of runs.
     * @return the number of runs.
     */
    public long runCount() {
        return runs;
    }

    /**
     * Get the number of failures.
     * @return the number of failures.
     */
    public long failureCount() {
        return failures;
    }

    /**
     * Get the number of errors.
     * @return the number of errors.
     */
    public long errorCount() {
        return errors;
    }

    /**
     * Get the number of skipped tests.
     * @return the number of skipped tests.
     */
    public long skipCount() {
        return skips;
    }

    /**
     * Get the run time.
     * @return the run time in milliseconds.
     */
    public long getRunTime() {
        return runTime;
    }

    /**
     * Get the properties used in the test.
     * @return the properties.
     */
    public Properties getProperties() {
        return props;
    }

    /**
     * Set the properties to be used in the test.
     * @param p the properties.
     *          This is a copy of the projects ant properties.
     */
    public void setProperties(Hashtable p) {
        props = new Properties();
        for (Enumeration e = p.keys(); e.hasMoreElements();) {
            Object key = e.nextElement();
            props.put(key, p.get(key));
        }
    }

    /**
     * Check if this test should run based on the if and unless
     * attributes.
     * @param p the project to use to check if the if and unless
     *          properties exist in.
     * @return true if this test or testsuite should be run.
     */
    public boolean shouldRun(Project p) {
        PropertyHelper ph = PropertyHelper.getPropertyHelper(p);
        return ph.testIfCondition(getIfCondition())
            && ph.testUnlessCondition(getUnlessCondition());
    }

    /**
     * Get the formatters set for this test.
     * @return the formatters as an array.
     */
    public FormatterElement[] getFormatters() {
        FormatterElement[] fes = new FormatterElement[formatters.size()];
        formatters.copyInto(fes);
        return fes;
    }

    /**
     * Convenient method to add formatters to a vector
     */
    void addFormattersTo(Vector v) {
        final int count = formatters.size();
        for (int i = 0; i < count; i++) {
            v.addElement(formatters.elementAt(i));
        }
    }

    /**
     * @since Ant 1.5
     * @return a clone of this test.
     */
    @Override
    public Object clone() {
        try {
            JUnitTest t = (JUnitTest) super.clone();
            t.props = props == null ? null : (Properties) props.clone();
            t.formatters = (Vector) formatters.clone();
            return t;
        } catch (CloneNotSupportedException e) {
            // plain impossible
            return this;
        }
    }
}
