package org.apache.maven.continuum.buildcontroller;

/*
 * 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.continuum.taskqueue.BuildProjectTask;
import org.apache.maven.continuum.AbstractContinuumTest;
import org.apache.maven.continuum.core.action.AbstractContinuumAction;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectGroup;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuilder;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuilderException;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
import org.apache.maven.continuum.project.builder.maven.MavenTwoContinuumProjectBuilder;
import org.codehaus.plexus.action.ActionManager;
import org.codehaus.plexus.taskqueue.Task;
import org.codehaus.plexus.taskqueue.TaskQueue;
import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
 */
public class BuildProjectTaskExecutorTest
    extends AbstractContinuumTest
{
    private ContinuumProjectBuilder projectBuilder;

    private TaskQueue buildQueue;

    private TaskQueueExecutor taskQueueExecutor;

    private ActionManager actionManager;

    public void setUp()
        throws Exception
    {
        try
        {
            super.setUp();

            projectBuilder =
                (ContinuumProjectBuilder) lookup( ContinuumProjectBuilder.ROLE, MavenTwoContinuumProjectBuilder.ID );

            buildQueue = (TaskQueue) lookup( TaskQueue.ROLE, "build-project" );

            taskQueueExecutor = (TaskQueueExecutor) lookup( TaskQueueExecutor.ROLE, "build-project" );

            actionManager = (ActionManager) lookup( ActionManager.ROLE );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            throw e;
        }
    }

    public void testAutomaticCancellation()
        throws Exception
    {
        runTimeoutProject( 13000 );

        long taskStartTime = System.currentTimeMillis();

        // should be killed in 5 secs, plus slack
        waitForTaskDead( 10000 );

        // the project will sleep for 15 seconds and then write a file.
        // Make sure we sleep at least that long and then check for the file;
        // it should not be there.

        long taskWaitTime = 15000 - ( System.currentTimeMillis() - taskStartTime );

        System.err.println( "Sleeping " + taskWaitTime + "ms" );
        Thread.sleep( taskWaitTime );

        assertFalse( "Build completed", getTestFile( "src/test-projects/timeout/target/TEST-COMPLETED" ).exists() );
    }

    public void testManualCancellation()
        throws Exception
    {
        BuildProjectTask task = runTimeoutProject( 0 );

        assertFalse( "Build completed", getTestFile( "src/test-projects/timeout/target/TEST-COMPLETED" ).exists() );

        long taskStartTime = System.currentTimeMillis();

        assertTrue( taskQueueExecutor.cancelTask( task ) );

        waitForTaskDead( 5000 );

        long taskWaitTime = 15000 - ( System.currentTimeMillis() - taskStartTime );

        System.err.println( "Sleeping " + taskWaitTime + "ms" );
        Thread.sleep( taskWaitTime );

        assertFalse( "Build completed", getTestFile( "src/test-projects/timeout/target/TEST-COMPLETED" ).exists() );
    }

    public void testNoCancellation()
        throws Exception
    {
        runTimeoutProject( 0 );

        waitForFile( "src/test-projects/timeout/target/TEST-COMPLETED", 20000 );

        waitForTaskDead( 10000 );
    }

    private void waitForFile( String file, int max )
        throws InterruptedException
    {
        long time = System.currentTimeMillis();

        for ( int i = 0; i < max / 10; i++ )
        {
            if ( getTestFile( file ).exists() )
            {
                break;
            }
            Thread.sleep( 10 );
        }

        System.err.println( "Waited " + ( System.currentTimeMillis() - time ) + "ms for file " + file );

        assertTrue( "File " + file, getTestFile( file ).exists() );
    }

    private void waitForTaskDead( int maxWait )
        throws InterruptedException
    {
        for ( int i = 0; i < maxWait / 10; i++ )
        {
            if ( taskQueueExecutor.getCurrentTask() == null )
            {
                break;
            }

            Thread.sleep( 10 );
        }

        assertNull( "No current task", taskQueueExecutor.getCurrentTask() );
    }

    /**
     * Runs the timeout test project through the build queue and return when the unit test in it has started. The
     * project contains a unit test that sleeps for 15 seconds.
     *
     * @param maxRunTime maximum time the build may run before it's auto cancelled; 0 means forever.
     * @return
     * @throws Exception
     */
    private BuildProjectTask runTimeoutProject( int maxRunTime )
        throws Exception
    {
        BuildProjectTask task = createTask( maxRunTime );

        FileUtils.forceDelete( getTestFile( "src/test-projects/timeout/target/TEST-STARTED" ) );
        FileUtils.forceDelete( getTestFile( "src/test-projects/timeout/target/TEST-COMPLETED" ) );

        System.err.println( "Queueing build" );

        this.buildQueue.put( task );

        System.err.println( "Waiting for task to start" );

        Task curTask = null;

        // Sleep at most 10 seconds for the task to start
        for ( int i = 0; i < 1000; i++ )
        {
            curTask = taskQueueExecutor.getCurrentTask();

            if ( curTask != null )
            {
                break;
            }

            Thread.sleep( 10 );
        }

        assertNotNull( "Task not started", task );

        // wait for the start file to be written

        waitForFile( "src/test-projects/timeout/target/TEST-STARTED", 10000 );

        System.err.println( "Task started, TEST-STARTED file created." );

        return task;
    }

    private BuildProjectTask createTask( int maxRunTime )
        throws Exception
    {
        ProjectGroup projectGroup = getProjectGroup( "src/test-projects/timeout/pom.xml" );
        Project project = (Project) projectGroup.getProjects().get( 0 );

        BuildDefinition buildDefinition = new BuildDefinition();
        buildDefinition.setId( 0 );
        buildDefinition.setGoals( "install" );

        projectGroup.addBuildDefinition( buildDefinition );

        Map pgContext = new HashMap();

        pgContext.put( AbstractContinuumAction.KEY_WORKING_DIRECTORY, project.getWorkingDirectory() );

        pgContext.put( AbstractContinuumAction.KEY_UNVALIDATED_PROJECT_GROUP, projectGroup );

        actionManager.lookup( "validate-project-group" ).execute( pgContext );

        actionManager.lookup( "store-project-group" ).execute( pgContext );

        int projectGroupId = AbstractContinuumAction.getProjectGroupId( pgContext );

        projectGroup = getProjectGroupDao().getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );

        project = (Project) projectGroup.getProjects().get( 0 );

        buildDefinition = (BuildDefinition) projectGroup.getBuildDefinitions().get( 0 );

        // projectGroup = continuumStore.addProjectGroup( projectGroup );

        BuildProjectTask task = new BuildProjectTask( project.getId(), buildDefinition.getId(), 0, project.getName(),
                                                      buildDefinition.getDescription() );

        task.setMaxExecutionTime( maxRunTime );

        return task;
    }

    private ProjectGroup getProjectGroup( String pomResource )
        throws ContinuumProjectBuilderException, IOException
    {
        File pom = getTestFile( pomResource );

        assertNotNull( "Can't find project " + pomResource, pom );

        ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null );

        // some assertions to make sure our expectations match. This is NOT
        // meant as a unit test for the projectbuilder!

        assertNotNull( "Project list not null", result.getProjects() );

        assertEquals( "#Projectgroups", 1, result.getProjectGroups().size() );

        ProjectGroup pg = (ProjectGroup) result.getProjectGroups().get( 0 );

        // If the next part fails, remove this code! Then result.getProjects
        // might be empty, and result.projectgroups[0].getProjects contains
        // the single project!

        assertEquals( "#Projects in result", 1, result.getProjects().size() );

        Project p = (Project) result.getProjects().get( 0 );

        pg.addProject( p );

        p.setWorkingDirectory( pom.getParent() );

        return pg;
    }
}
