/*
 *  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
 *
 *      https://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.io.OutputStream;
import java.lang.reflect.Method;

import junit.framework.AssertionFailedError;
import junit.framework.Test;

/**
 * Formatter that doesn't create any output but tries to invoke the
 * tearDown method on a testcase if that test was forked and caused a
 * timeout or VM crash.
 *
 * <p>This formatter has some limitations, for details see the
 * &lt;junit&gt; task's manual.</p>
 *
 * @since Ant 1.8.0
 */
public class TearDownOnVmCrash implements JUnitResultFormatter {

    private String suiteName;

    /**
     * Records the suite's name to later determine the class to invoke
     * tearDown on.
     */
    @Override
    public void startTestSuite(final JUnitTest suite) {
        suiteName = suite.getName();
        if (suiteName != null && suiteName.endsWith(JUnitTask.NAME_OF_DUMMY_TEST)) {
            // no way to know which class caused the timeout
            suiteName = null;
        }
    }

    /**
     * Only invoke tearDown if the suite is known and not the dummy
     * test we get when a Batch fails and the error is an actual
     * error generated by Ant.
     */
    @Override
    public void addError(final Test fakeTest, final Throwable t) {
        if (suiteName != null && fakeTest instanceof JUnitTaskMirrorImpl.VmExitErrorTest) {
            tearDown();
        }
    }

    // no need to implement the rest
    public void addFailure(Test test, Throwable t) {
    }

    @Override
    public void addFailure(Test test, AssertionFailedError t) {
    }

    @Override
    public void startTest(Test test) {
    }

    @Override
    public void endTest(Test test) {
    }

    @Override
    public void endTestSuite(JUnitTest suite) {
    }

    @Override
    public void setOutput(OutputStream out) {
    }

    @Override
    public void setSystemOutput(String out) {
    }

    @Override
    public void setSystemError(String err) {
    }

    private void tearDown() {
        try {
            // first try to load the class and let's hope it is on our
            // classpath
            Class<?> testClass = null;
            if (Thread.currentThread().getContextClassLoader() != null) {
                try {
                    testClass = Thread.currentThread().getContextClassLoader()
                        .loadClass(suiteName);
                } catch (ClassNotFoundException cnfe) {
                    // ignore
                }
            }
            if (testClass == null && getClass().getClassLoader() != null) {
                try {
                    testClass = getClass().getClassLoader().loadClass(suiteName);
                } catch (ClassNotFoundException cnfe) {
                    // ignore
                }
            }
            if (testClass == null) {
                // fall back to system classloader
                testClass = Class.forName(suiteName);
            }

            // if the test has a suite method, then we can't know
            // which test of the executed suite timed out, ignore it
            try {
                // check if there is a suite method
                testClass.getMethod("suite");
                return;
            } catch (NoSuchMethodException e) {
                // no suite method
            }

            // a loadable class and no suite method
            // no reason to check for JUnit 4 since JUnit4TestAdapter
            // doesn't have any tearDown method.

            try {
                Method td = testClass.getMethod("tearDown");
                if (td.getReturnType() == Void.TYPE) {
                    td.invoke(testClass.newInstance());
                }
            } catch (NoSuchMethodException nsme) {
                // no tearDown, fine
            }

        } catch (ClassNotFoundException cnfe) {
            // class probably is not in our classpath, there is
            // nothing we can do
        } catch (Throwable t) {
            System.err.println("Caught an exception while trying to invoke"
                               + " tearDown: " + t.getMessage());
        }
    }
}
