/*
 * 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.directory.server.core.integ;


import java.lang.reflect.Method;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.directory.api.ldap.codec.standalone.StandaloneLdapApiService;
import org.apache.directory.server.annotations.CreateKdcServer;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.changelog.ChangeLog;
import org.apache.directory.server.core.factory.DSAnnotationProcessor;
import org.apache.directory.server.core.factory.DefaultDirectoryServiceFactory;
import org.apache.directory.server.core.factory.DirectoryServiceFactory;
import org.apache.directory.server.core.factory.PartitionFactory;
import org.apache.directory.server.factory.ServerAnnotationProcessor;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.kerberos.kdc.KdcServer;
import org.apache.directory.server.ldap.LdapServer;
import org.junit.Ignore;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * The class responsible for running all the tests. t read the annotations, 
 * initialize the DirectoryService, call each test and do the cleanup at the end.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class FrameworkRunner extends BlockJUnit4ClassRunner
{
    /** A logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( FrameworkRunner.class );

    /** The 'service' field in the run tests */
    private static final String SET_SERVICE_METHOD_NAME = "setService";

    /** The 'ldapServer' field in the run tests */
    private static final String SET_LDAP_SERVER_METHOD_NAME = "setLdapServer";

    /** The 'kdcServer' field in the run tests */
    private static final String SET_KDC_SERVER_METHOD_NAME = "setKdcServer";

    /** The DirectoryService for this class, if any */
    private DirectoryService classDS;

    /** The LdapServer for this class, if any */
    private LdapServer classLdapServer;

    /** The KdcServer for this class, if any */
    private KdcServer classKdcServer;


    /**
     * Creates a new instance of FrameworkRunner.
     */
    public FrameworkRunner( Class<?> clazz ) throws InitializationError
    {
        super( clazz );
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void run( final RunNotifier notifier )
    {
        // Before running any test, check to see if we must create a class DS
        // Get the LdapServerBuilder, if any
        CreateLdapServer classLdapServerBuilder = getDescription().getAnnotation( CreateLdapServer.class );

        try
        {
            classDS = DSAnnotationProcessor.getDirectoryService( getDescription() );
            long revision = 0L;
            DirectoryService directoryService = null;

            if ( classDS != null )
            {
                // We have a class DS defined, update it
                directoryService = classDS;

                DSAnnotationProcessor.applyLdifs( getDescription(), classDS );
            }
            else
            {
                // No : define a default class DS then
                DirectoryServiceFactory dsf = DefaultDirectoryServiceFactory.class.newInstance();

                directoryService = dsf.getDirectoryService();
                // enable CL explicitly cause we are not using DSAnnotationProcessor
                directoryService.getChangeLog().setEnabled( true );

                dsf.init( "default" + UUID.randomUUID().toString() );

                // Stores the defaultDS in the classDS
                classDS = directoryService;

                // Load the schemas
                DSAnnotationProcessor.loadSchemas( getDescription(), directoryService );

                // Apply the class LDIFs
                DSAnnotationProcessor.applyLdifs( getDescription(), directoryService );
            }

            // check if it has a LdapServerBuilder
            // then use the DS created above
            if ( classLdapServerBuilder != null )
            {
                classLdapServer = ServerAnnotationProcessor.createLdapServer( getDescription(), directoryService );
            }

            if ( classKdcServer == null )
            {
                int minPort = getMinPort();

                classKdcServer = ServerAnnotationProcessor.getKdcServer( getDescription(), directoryService,
                    minPort + 1 );
            }

            // print out information which partition factory we use
            DirectoryServiceFactory dsFactory = DefaultDirectoryServiceFactory.class.newInstance();
            PartitionFactory partitionFactory = dsFactory.getPartitionFactory();
            LOG.debug( "Using partition factory {}", partitionFactory.getClass().getSimpleName() );

            // Now run the class
            super.run( notifier );

            if ( classLdapServer != null )
            {
                classLdapServer.stop();
            }

            if ( classKdcServer != null )
            {
                classKdcServer.stop();
            }

            // cleanup classService if it is not the same as suite service or
            // it is not null (this second case happens in the absence of a suite)
            if ( classDS != null )
            {
                LOG.debug( "Shuting down DS for {}", classDS.getInstanceId() );
                classDS.shutdown();
                FileUtils.deleteDirectory( classDS.getInstanceLayout().getInstanceDirectory() );
            }
            else
            {
                // Revert the ldifs
                // We use a class or suite DS, just revert the current test's modifications
                revert( directoryService, revision );
            }
        }
        catch ( Exception e )
        {
            LOG.error( I18n.err( I18n.ERR_181, getTestClass().getName() ) );
            LOG.error( e.getLocalizedMessage() );
            notifier.fireTestFailure( new Failure( getDescription(), e ) );
        }
        finally
        {
            // help GC to get rid of the directory service with all its references
            classDS = null;
            classLdapServer = null;
            classKdcServer = null;
        }
    }


    /**
     * Get the lower port out of all the transports
     */
    private int getMinPort()
    {
        int minPort = 0;

        return minPort;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    protected void runChild( FrameworkMethod method, RunNotifier notifier )
    {
        /** The LdapServer for this method, if any */
        LdapServer methodLdapServer = null;

        /** The KdcServer for this method, if any */
        KdcServer methodKdcServer = null;

        // Don't run the test if the @Ignored annotation is used
        if ( method.getAnnotation( Ignore.class ) != null )
        {
            Description description = describeChild( method );
            notifier.fireTestIgnored( description );
            return;
        }

        // Get the applyLdifs for each level
        Description suiteDescription = null;

        Description classDescription = getDescription();
        Description methodDescription = describeChild( method );

        // Before running any test, check to see if we must create a class DS
        // Get the LdapServerBuilder, if any
        CreateLdapServer methodLdapServerBuilder = methodDescription.getAnnotation( CreateLdapServer.class );
        CreateKdcServer methodKdcServerBuilder = methodDescription.getAnnotation( CreateKdcServer.class );

        // Ok, ready to run the test
        try
        {
            DirectoryService directoryService = null;

            // Set the revision to 0, we will revert only if it's set to another value
            long revision = 0L;

            // Check if this method has a dedicated DSBuilder
            DirectoryService methodDS = DSAnnotationProcessor.getDirectoryService( methodDescription );

            // give #1 priority to method level DS if present
            if ( methodDS != null )
            {
                // Apply all the LDIFs
                DSAnnotationProcessor.applyLdifs( suiteDescription, methodDS );
                DSAnnotationProcessor.applyLdifs( classDescription, methodDS );
                DSAnnotationProcessor.applyLdifs( methodDescription, methodDS );

                directoryService = methodDS;
            }
            else if ( classDS != null )
            {
                directoryService = classDS;

                // apply the method LDIFs, and tag for reversion
                revision = getCurrentRevision( directoryService );

                DSAnnotationProcessor.applyLdifs( methodDescription, directoryService );
            }
            // we don't support method level LdapServer so
            // we check for the presence of Class level LdapServer first 
            else if ( classLdapServer != null )
            {
                directoryService = classLdapServer.getDirectoryService();

                revision = getCurrentRevision( directoryService );

                DSAnnotationProcessor.applyLdifs( methodDescription, directoryService );
            }
            else if ( classKdcServer != null )
            {
                directoryService = classKdcServer.getDirectoryService();

                revision = getCurrentRevision( directoryService );

                DSAnnotationProcessor.applyLdifs( methodDescription, directoryService );
            }

            if ( methodLdapServerBuilder != null )
            {
                methodLdapServer = ServerAnnotationProcessor.createLdapServer( methodDescription, directoryService );
            }

            if ( methodKdcServerBuilder != null )
            {
                int minPort = getMinPort();

                methodKdcServer = ServerAnnotationProcessor.getKdcServer( methodDescription, directoryService,
                    minPort + 1 );
            }

            // At this point, we know which service to use.
            // Inject it into the class
            Method setService = null;

            try
            {
                setService = getTestClass().getJavaClass().getMethod( SET_SERVICE_METHOD_NAME,
                    DirectoryService.class );

                setService.invoke( getTestClass().getJavaClass(), directoryService );
            }
            catch ( NoSuchMethodException nsme )
            {
                // Do nothing
            }

            // if we run this class in a suite, tell it to the test
            Method setLdapServer = null;

            try
            {
                setLdapServer = getTestClass().getJavaClass().getMethod( SET_LDAP_SERVER_METHOD_NAME,
                    LdapServer.class );
            }
            catch ( NoSuchMethodException nsme )
            {
                // Do nothing
            }

            Method setKdcServer = null;

            try
            {
                setKdcServer = getTestClass().getJavaClass().getMethod( SET_KDC_SERVER_METHOD_NAME, KdcServer.class );
            }
            catch ( NoSuchMethodException nsme )
            {
                // Do nothing
            }

            DirectoryService oldLdapServerDirService = null;
            DirectoryService oldKdcServerDirService = null;

            if ( methodLdapServer != null )
            {
                // setting the directoryService is required to inject the correct level DS instance in the class or suite level LdapServer
                methodLdapServer.setDirectoryService( directoryService );

                setLdapServer.invoke( getTestClass().getJavaClass(), methodLdapServer );
            }
            else if ( classLdapServer != null )
            {
                oldLdapServerDirService = classLdapServer.getDirectoryService();

                // setting the directoryService is required to inject the correct level DS instance in the class or suite level LdapServer
                classLdapServer.setDirectoryService( directoryService );

                setLdapServer.invoke( getTestClass().getJavaClass(), classLdapServer );
            }

            if ( methodKdcServer != null )
            {
                // setting the directoryService is required to inject the correct level DS instance in the class or suite level KdcServer
                methodKdcServer.setDirectoryService( directoryService );

                setKdcServer.invoke( getTestClass().getJavaClass(), methodKdcServer );
            }
            else if ( classKdcServer != null )
            {
                oldKdcServerDirService = classKdcServer.getDirectoryService();

                // setting the directoryService is required to inject the correct level DS instance in the class or suite level KdcServer
                classKdcServer.setDirectoryService( directoryService );

                setKdcServer.invoke( getTestClass().getJavaClass(), classKdcServer );
            }

            // Run the test
            super.runChild( method, notifier );

            if ( methodLdapServer != null )
            {
                methodLdapServer.stop();
            }

            if ( oldLdapServerDirService != null )
            {
                classLdapServer.setDirectoryService( oldLdapServerDirService );
            }

            if ( oldKdcServerDirService != null )
            {
                classKdcServer.setDirectoryService( oldKdcServerDirService );
            }

            // Cleanup the methodDS if it has been created
            if ( methodDS != null )
            {
                LOG.debug( "Shuting down DS for {}", methodDS.getInstanceId() );
                methodDS.shutdown();
                FileUtils.deleteDirectory( methodDS.getInstanceLayout().getInstanceDirectory() );
            }
            else
            {
                // We use a class or suite DS, just revert the current test's modifications
                revert( directoryService, revision );
            }
        }
        catch ( Exception e )
        {
            LOG.error( I18n.err( I18n.ERR_182, method.getName() ) );
            LOG.error( "", e );
            notifier.fireTestFailure( new Failure( getDescription(), e ) );
        }
    }


    private long getCurrentRevision( DirectoryService dirService ) throws Exception
    {
        if ( ( dirService != null ) && ( dirService.getChangeLog().isEnabled() ) )
        {
            long revision = dirService.getChangeLog().getCurrentRevision();
            LOG.debug( "Create revision {}", revision );

            return revision;
        }

        return 0;
    }


    private void revert( DirectoryService dirService, long revision ) throws Exception
    {
        if ( dirService == null )
        {
            return;
        }

        ChangeLog cl = dirService.getChangeLog();
        if ( cl.isEnabled() && ( revision < cl.getCurrentRevision() ) )
        {
            LOG.debug( "Revert revision {}", revision );
            dirService.revert( revision );
        }
    }
}
