package org.apache.maven.surefire.common.junit4;

/*
 * 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.
 */

import org.apache.maven.surefire.api.report.ReportEntry;
import org.apache.maven.surefire.api.report.RunListener;
import org.apache.maven.surefire.api.report.SimpleReportEntry;
import org.apache.maven.surefire.api.report.StackTraceWriter;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.apache.maven.surefire.api.util.internal.ClassMethod;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod;
import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
import static org.apache.maven.surefire.api.report.SimpleReportEntry.assumption;
import static org.apache.maven.surefire.api.report.SimpleReportEntry.ignored;
import static org.apache.maven.surefire.api.report.SimpleReportEntry.withException;

/**
 * RunListener for JUnit4, delegates to our own RunListener
 *
 */
public class JUnit4RunListener
    extends org.junit.runner.notification.RunListener
{
    protected final RunListener reporter;

    /**
     * This flag is set after a failure has occurred so that a {@link RunListener#testSucceeded} event is not fired.
     * This is necessary because JUnit4 always fires a
     * {@link org.junit.runner.notification.RunListener#testRunFinished(Result)}
     * event-- even if there was a failure.
     */
    private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<>();

    /**
     * Constructor.
     *
     * @param reporter the reporter to log testing events to
     */
    public JUnit4RunListener( RunListener reporter )
    {
        this.reporter = reporter;
    }

    // Testrun methods are not invoked when using the runner

    /**
     * Called when a specific test has been skipped (for whatever reason).
     *
     * @see org.junit.runner.notification.RunListener#testIgnored(org.junit.runner.Description)
     */
    @Override
    public void testIgnored( Description description )
        throws Exception
    {
        String reason = getAnnotatedIgnoreValue( description );
        ClassMethod classMethod = toClassMethod( description );
        reporter.testSkipped( ignored( classMethod.getClazz(), null, classMethod.getMethod(), null, reason ) );
    }

    /**
     * Called when a specific test has started.
     *
     * @see org.junit.runner.notification.RunListener#testStarted(org.junit.runner.Description)
     */
    @Override
    public void testStarted( Description description )
        throws Exception
    {
        try
        {
            reporter.testStarting( createReportEntry( description ) );
        }
        finally
        {
            failureFlag.remove();
        }
    }

    /**
     * Called when a specific test has failed.
     *
     * @see org.junit.runner.notification.RunListener#testFailure(org.junit.runner.notification.Failure)
     */
    @Override
    @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" } )
    public void testFailure( Failure failure )
        throws Exception
    {
        try
        {
            StackTraceWriter stackTrace = createStackTraceWriter( failure );
            ClassMethod classMethod = toClassMethod( failure.getDescription() );
            ReportEntry report =
                    withException( classMethod.getClazz(), null, classMethod.getMethod(), null, stackTrace );

            if ( failure.getException() instanceof AssertionError )
            {
                reporter.testFailed( report );
            }
            else
            {
                reporter.testError( report );
            }
        }
        finally
        {
            failureFlag.set( true );
        }
    }

    public void testAssumptionFailure( Failure failure )
    {
        try
        {
            Description desc = failure.getDescription();
            ClassMethod classMethod = toClassMethod( desc );
            ReportEntry report = assumption( classMethod.getClazz(), null, classMethod.getMethod(), null,
                    failure.getMessage() );
            reporter.testAssumptionFailure( report );
        }
        finally
        {
            failureFlag.set( true );
        }
    }

    /**
     * Called after a specific test has finished.
     *
     * @see org.junit.runner.notification.RunListener#testFinished(org.junit.runner.Description)
     */
    @Override
    public void testFinished( Description description )
        throws Exception
    {
        Boolean failure = failureFlag.get();
        if ( failure == null )
        {
            reporter.testSucceeded( createReportEntry( description ) );
        }
    }

    /**
     * Delegates to {@link RunListener#testExecutionSkippedByUser()}.
     */
    public void testExecutionSkippedByUser()
    {
        reporter.testExecutionSkippedByUser();
    }

    protected StackTraceWriter createStackTraceWriter( Failure failure )
    {
        return new JUnit4StackTraceWriter( failure );
    }

    protected SimpleReportEntry createReportEntry( Description description )
    {
        ClassMethod classMethod = toClassMethod( description );
        return new SimpleReportEntry( classMethod.getClazz(), null, classMethod.getMethod(), null );
    }

    public static void rethrowAnyTestMechanismFailures( Result run )
        throws TestSetFailedException
    {
        for ( Failure failure : run.getFailures() )
        {
            if ( isFailureInsideJUnitItself( failure.getDescription() ) )
            {
                throw new TestSetFailedException( failure.getTestHeader() + " :: " + failure.getMessage(),
                                                        failure.getException() );
            }
        }
    }
}
