package org.apache.maven.surefire.junit;

/*
 * 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.common.junit3.JUnit3Reflector;
import org.apache.maven.surefire.common.junit3.JUnit3TestChecker;
import org.apache.maven.surefire.api.provider.AbstractProvider;
import org.apache.maven.surefire.api.provider.ProviderParameters;
import org.apache.maven.surefire.api.report.ConsoleOutputCapture;
import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.api.report.ReporterFactory;
import org.apache.maven.surefire.api.report.RunListener;
import org.apache.maven.surefire.api.report.SimpleReportEntry;
import org.apache.maven.surefire.api.report.TestSetReportEntry;
import org.apache.maven.surefire.api.suite.RunResult;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.apache.maven.surefire.api.util.ReflectionUtils;
import org.apache.maven.surefire.api.util.RunOrderCalculator;
import org.apache.maven.surefire.api.util.ScanResult;
import org.apache.maven.surefire.api.util.TestsToRun;

import java.util.Map;

import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;

/**
 * @author Kristian Rosenvold
 */
public class JUnit3Provider
    extends AbstractProvider
{
    private final ClassLoader testClassLoader;

    private final PojoAndJUnit3Checker testChecker;

    private final JUnit3TestChecker jUnit3TestChecker;

    private final JUnit3Reflector reflector;

    private final ProviderParameters providerParameters;

    private final RunOrderCalculator runOrderCalculator;

    private final ScanResult scanResult;

    private TestsToRun testsToRun;

    public JUnit3Provider( ProviderParameters booterParameters )
    {
        this.providerParameters = booterParameters;
        testClassLoader = booterParameters.getTestClassLoader();
        scanResult = booterParameters.getScanResult();
        runOrderCalculator = booterParameters.getRunOrderCalculator();
        reflector = new JUnit3Reflector( testClassLoader );
        jUnit3TestChecker = new JUnit3TestChecker( testClassLoader );
        testChecker = new PojoAndJUnit3Checker( jUnit3TestChecker ); // Todo; use reflector
    }

    @Override
    public RunResult invoke( Object forkTestSet )
        throws TestSetFailedException
    {
        if ( testsToRun == null )
        {
            if ( forkTestSet instanceof TestsToRun )
            {
                testsToRun = (TestsToRun) forkTestSet;
            }
            else if ( forkTestSet instanceof Class )
            {
                testsToRun = TestsToRun.fromClass( (Class<?>) forkTestSet );
            }
            else
            {
                testsToRun = scanClassPath();
            }
        }

        ReporterFactory reporterFactory = providerParameters.getReporterFactory();
        RunResult runResult;
        try
        {
            final RunListener reporter = reporterFactory.createReporter();
            ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
            Map<String, String> systemProperties = systemProps();
            String smClassName = System.getProperty( "surefire.security.manager" );
            if ( smClassName != null )
            {
                SecurityManager securityManager =
                    ReflectionUtils.instantiate( getClass().getClassLoader(), smClassName, SecurityManager.class );
                System.setSecurityManager( securityManager );
            }

            for ( Class<?> clazz : testsToRun )
            {
                SurefireTestSet surefireTestSet = createTestSet( clazz );
                executeTestSet( surefireTestSet, reporter, testClassLoader, systemProperties );
            }
        }
        finally
        {
            runResult = reporterFactory.close();
        }
        return runResult;
    }

    private SurefireTestSet createTestSet( Class<?> clazz )
    {
        return reflector.isJUnit3Available() && jUnit3TestChecker.accept( clazz )
            ? new JUnitTestSet( clazz, reflector )
            : new PojoTestSet( clazz );
    }

    private void executeTestSet( SurefireTestSet testSet, RunListener reporter, ClassLoader classLoader,
                                 Map<String, String> systemProperties )
        throws TestSetFailedException
    {
        String clazz = testSet.getName();

        try
        {
            TestSetReportEntry started = new SimpleReportEntry( clazz, null, null, null );
            reporter.testSetStarting( started );
            testSet.execute( reporter, classLoader );
        }
        finally
        {
            TestSetReportEntry completed = new SimpleReportEntry( clazz, null, null, null, systemProperties );
            reporter.testSetCompleted( completed );
        }
    }

    private TestsToRun scanClassPath()
    {
        final TestsToRun testsToRun = scanResult.applyFilter( testChecker, testClassLoader );
        return runOrderCalculator.orderTestClasses( testsToRun );
    }

    @Override
    public Iterable<Class<?>> getSuites()
    {
        testsToRun = scanClassPath();
        return testsToRun;
    }
}
