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.dao.BuildDefinitionDao;
import org.apache.continuum.dao.BuildResultDao;
import org.apache.continuum.dao.ProjectDao;
import org.apache.maven.continuum.core.action.AbstractContinuumAction;
import org.apache.maven.continuum.execution.ContinuumBuildExecutor;
import org.apache.maven.continuum.execution.manager.BuildExecutorManager;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.BuildResult;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectDependency;
import org.apache.maven.continuum.model.scm.ChangeFile;
import org.apache.maven.continuum.model.scm.ChangeSet;
import org.apache.maven.continuum.model.scm.ScmResult;
import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
import org.apache.maven.continuum.project.ContinuumProjectState;
import org.apache.maven.continuum.store.ContinuumObjectNotFoundException;
import org.apache.maven.continuum.store.ContinuumStoreException;
import org.apache.maven.continuum.utils.ContinuumUtils;
import org.apache.maven.continuum.utils.WorkingDirectoryService;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.repository.ScmRepositoryException;
import org.codehaus.plexus.action.ActionManager;
import org.codehaus.plexus.action.ActionNotFoundException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
import org.codehaus.plexus.util.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 * @version $Id$
 * @plexus.component role="org.apache.maven.continuum.buildcontroller.BuildController" role-hint="default"
 */
public class DefaultBuildController
    extends AbstractLogEnabled
    implements BuildController
{
    /**
     * @plexus.requirement
     */
    private BuildDefinitionDao buildDefinitionDao;

    /**
     * @plexus.requirement
     */
    private BuildResultDao buildResultDao;

    /**
     * @plexus.requirement
     */
    private ProjectDao projectDao;

    /**
     * @plexus.requirement
     */
    private ContinuumNotificationDispatcher notifierDispatcher;

    /**
     * @plexus.requirement
     */
    private ActionManager actionManager;

    /**
     * @plexus.requirement
     */
    private WorkingDirectoryService workingDirectoryService;

    /**
     * @plexus.requirement
     */
    private BuildExecutorManager buildExecutorManager;

    // ----------------------------------------------------------------------
    // BuildController Implementation
    // ----------------------------------------------------------------------

    /**
     * @param projectId
     * @param buildDefinitionId
     * @param trigger
     * @throws TaskExecutionException
     */
    public void build( int projectId, int buildDefinitionId, int trigger )
        throws TaskExecutionException
    {
        getLogger().info( "Initializing build" );
        BuildContext context = initializeBuildContext( projectId, buildDefinitionId, trigger );

        getLogger().info( "Starting build of " + context.getProject().getName() );
        startBuild( context );

        try
        {
            // check if build definition requires smoking the existing checkout and rechecking out project
            if ( context.getBuildDefinition().isBuildFresh() )
            {
                getLogger().info( "Purging exiting working copy" );
                cleanWorkingDirectory( context );
            }

            // ----------------------------------------------------------------------
            // TODO: Centralize the error handling from the SCM related actions.
            // ContinuumScmResult should return a ContinuumScmResult from all
            // methods, even in a case of failure.
            // ----------------------------------------------------------------------
            getLogger().info( "Updating working dir" );
            updateWorkingDirectory( context );

            getLogger().info( "Merging SCM results" );
            //CONTINUUM-1393
            if ( !context.getBuildDefinition().isBuildFresh() )
            {
                mergeScmResults( context );
            }

            // ignore this if AlwaysBuild ?
            if ( !checkScmResult( context ) )
            {
                getLogger().info( "Error updating from SCM, not building" );
                return;
            }

            checkProjectDependencies( context );

            if ( !shouldBuild( context ) )
            {
                return;
            }

            Map actionContext = context.getActionContext();

            try
            {
                performAction( "update-project-from-working-directory", context );
            }
            catch ( TaskExecutionException e )
            {
                //just log the error but don't stop the build from progressing in order not to suppress any build result messages there 
                getLogger().error( "Error executing action update-project-from-working-directory '", e );
            }

            performAction( "execute-builder", context );

            performAction( "deploy-artifact", context );

            String s = (String) actionContext.get( AbstractContinuumAction.KEY_BUILD_ID );

            if ( s != null )
            {
                try
                {
                    context.setBuildResult( buildResultDao.getBuildResult( Integer.valueOf( s ) ) );
                }
                catch ( NumberFormatException e )
                {
                    throw new TaskExecutionException( "Internal error: build id not an integer", e );
                }
                catch ( ContinuumObjectNotFoundException e )
                {
                    throw new TaskExecutionException( "Internal error: Cannot find build result", e );
                }
                catch ( ContinuumStoreException e )
                {
                    throw new TaskExecutionException( "Error loading build result", e );
                }
            }
        }
        finally
        {
            endBuild( context );
        }
    }

    /**
     * Checks if the build should be marked as ERROR and notifies the end of the build.
     *
     * @param context
     * @throws TaskExecutionException
     */
    private void endBuild( BuildContext context )
        throws TaskExecutionException
    {
        Project project = context.getProject();

        try
        {
            if ( project.getState() != ContinuumProjectState.NEW &&
                project.getState() != ContinuumProjectState.CHECKEDOUT &&
                project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED &&
                project.getState() != ContinuumProjectState.ERROR )
            {
                try
                {
                    String s = (String) context.getActionContext().get( AbstractContinuumAction.KEY_BUILD_ID );

                    if ( s != null )
                    {
                        BuildResult buildResult = buildResultDao.getBuildResult( Integer.valueOf( s ) );
                        project.setState( buildResult.getState() );
                    }
                    else
                    {
                        project.setState( ContinuumProjectState.ERROR );
                    }

                    projectDao.updateProject( project );
                }
                catch ( ContinuumStoreException e )
                {
                    throw new TaskExecutionException( "Error storing the project", e );
                }
            }
        }
        finally
        {
            notifierDispatcher.buildComplete( project, context.getBuildDefinition(), context.getBuildResult() );
        }
    }

    private void updateBuildResult( BuildContext context, String error )
        throws TaskExecutionException
    {
        BuildResult build = context.getBuildResult();

        if ( build == null )
        {
            build = makeAndStoreBuildResult( context, error );
        }
        else
        {
            updateBuildResult( build, context );

            build.setError( error );

            try
            {
                buildResultDao.updateBuildResult( build );

                build = buildResultDao.getBuildResult( build.getId() );

                context.setBuildResult( build );
            }
            catch ( ContinuumStoreException e )
            {
                throw new TaskExecutionException( "Error updating build result", e );
            }
        }

        context.getProject().setState( build.getState() );

        try
        {
            projectDao.updateProject( context.getProject() );
        }
        catch ( ContinuumStoreException e )
        {
            throw new TaskExecutionException( "Error updating project", e );
        }
    }

    private void updateBuildResult( BuildResult build, BuildContext context )
    {
        if ( build.getScmResult() == null && context.getScmResult() != null )
        {
            build.setScmResult( context.getScmResult() );
        }

        if ( build.getModifiedDependencies() == null && context.getModifiedDependencies() != null )
        {
            build.setModifiedDependencies( context.getModifiedDependencies() );
        }
    }

    private void startBuild( BuildContext context )
        throws TaskExecutionException
    {

        Project project = context.getProject();

        project.setOldState( project.getState() );

        project.setState( ContinuumProjectState.BUILDING );

        try
        {
            projectDao.updateProject( project );
        }
        catch ( ContinuumStoreException e )
        {
            throw new TaskExecutionException( "Error persisting project", e );
        }

        notifierDispatcher.buildStarted( project, context.getBuildDefinition() );

    }

    /**
     * Initializes a BuildContext for the build.
     *
     * @param projectId
     * @param buildDefinitionId
     * @param trigger
     * @return
     * @throws TaskExecutionException
     */
    protected BuildContext initializeBuildContext( int projectId, int buildDefinitionId, int trigger )
        throws TaskExecutionException
    {
        BuildContext context = new BuildContext();

        context.setStartTime( System.currentTimeMillis() );

        context.setTrigger( trigger );

        try
        {
            context.setProject( projectDao.getProject( projectId ) );

            BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );

            context.setBuildDefinition( buildDefinition );

            BuildResult oldBuildResult =
                buildResultDao.getLatestBuildResultForBuildDefinition( projectId, buildDefinitionId );

            context.setOldBuildResult( oldBuildResult );

            // CONTINUUM-1871 olamy if continuum is killed during building oldBuildResult will have a endTime 0
            // this means all changes since the project has been loaded in continuum will be in memory
            // now we will load all BuildResult with an Id bigger or equals than the oldBuildResult one
            if ( oldBuildResult != null )
            {
                context.setOldScmResult( getOldScmResults( projectId, oldBuildResult.getBuildNumber(), oldBuildResult.getEndTime() ) );
            }
        }
        catch ( ContinuumStoreException e )
        {
            throw new TaskExecutionException( "Error initializing the build context", e );
        }

        Map actionContext = context.getActionContext();

        actionContext.put( AbstractContinuumAction.KEY_PROJECT_ID, projectId );

        actionContext.put( AbstractContinuumAction.KEY_PROJECT, context.getProject() );

        actionContext.put( AbstractContinuumAction.KEY_BUILD_DEFINITION_ID, buildDefinitionId );

        actionContext.put( AbstractContinuumAction.KEY_BUILD_DEFINITION, context.getBuildDefinition() );

        actionContext.put( AbstractContinuumAction.KEY_TRIGGER, trigger );

        actionContext.put( AbstractContinuumAction.KEY_FIRST_RUN, context.getOldBuildResult() == null );

        return context;
    }

    private void cleanWorkingDirectory( BuildContext context )
        throws TaskExecutionException
    {
        performAction( "clean-working-directory", context );
    }

    private void updateWorkingDirectory( BuildContext context )
        throws TaskExecutionException
    {
        Map actionContext = context.getActionContext();

        performAction( "check-working-directory", context );

        boolean workingDirectoryExists =
            AbstractContinuumAction.getBoolean( actionContext, AbstractContinuumAction.KEY_WORKING_DIRECTORY_EXISTS );

        ScmResult scmResult;

        if ( workingDirectoryExists )
        {
            performAction( "update-working-directory-from-scm", context );

            scmResult = AbstractContinuumAction.getUpdateScmResult( actionContext, null );
        }
        else
        {
            Project project = (Project) actionContext.get( AbstractContinuumAction.KEY_PROJECT );

            actionContext.put( AbstractContinuumAction.KEY_WORKING_DIRECTORY,
                               workingDirectoryService.getWorkingDirectory( project ).getAbsolutePath() );

            performAction( "checkout-project", context );

            scmResult = AbstractContinuumAction.getCheckoutResult( actionContext, null );
        }

        context.setScmResult( scmResult );
    }

    private void performAction( String actionName, BuildContext context )
        throws TaskExecutionException
    {
        String error = null;
        TaskExecutionException exception = null;

        try
        {
            getLogger().info( "Performing action " + actionName );
            actionManager.lookup( actionName ).execute( context.getActionContext() );
            return;
        }
        catch ( ActionNotFoundException e )
        {
            error = ContinuumUtils.throwableToString( e );
            exception = new TaskExecutionException( "Error looking up action '" + actionName + "'", e );
        }
        catch ( ScmRepositoryException e )
        {
            error = getValidationMessages( e ) + "\n" + ContinuumUtils.throwableToString( e );

            exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e );
        }
        catch ( ScmException e )
        {
            error = ContinuumUtils.throwableToString( e );

            exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e );
        }
        catch ( Exception e )
        {
            exception = new TaskExecutionException( "Error executing action '" + actionName + "'", e );
            error = ContinuumUtils.throwableToString( exception );
        }

        // TODO: clean this up. We catch the original exception from the action, and then update the buildresult
        // for it - we need to because of the specialized error message for SCM.
        // If updating the buildresult fails, log the previous error and throw the new one.
        // If updating the buildresult succeeds, throw the original exception. The build result should NOT
        // be updated again - a TaskExecutionException is final, no further action should be taken upon it.

        try
        {
            updateBuildResult( context, error );
        }
        catch ( TaskExecutionException e )
        {
            getLogger().error( "Error updating build result after receiving the following exception: ", exception );
            throw e;
        }

        throw exception;
    }

    protected boolean shouldBuild( BuildContext context )
        throws TaskExecutionException
    {
        BuildDefinition buildDefinition = context.getBuildDefinition();
        if ( buildDefinition.isAlwaysBuild() )
        {
            getLogger().info( "AlwaysBuild configured, building" );
            return true;
        }
        if ( context.getOldBuildResult() == null )
        {
            getLogger().info( "The project was never be built with the current build definition, building" );
            return true;
        }

        Project project = context.getProject();

        //CONTINUUM-1428
        if ( project.getOldState() == ContinuumProjectState.ERROR ||
            context.getOldBuildResult().getState() == ContinuumProjectState.ERROR )
        {
            getLogger().info( "Latest state was 'ERROR', building" );
            return true;
        }

        if ( context.getTrigger() == ContinuumProjectState.TRIGGER_FORCED )
        {
            getLogger().info( "The project build is forced, building" );
            return true;
        }

        boolean shouldBuild = false;

        boolean allChangesUnknown = true;

        if ( project.getOldState() != ContinuumProjectState.NEW &&
            project.getOldState() != ContinuumProjectState.CHECKEDOUT &&
            context.getTrigger() != ContinuumProjectState.TRIGGER_FORCED &&
            project.getState() != ContinuumProjectState.NEW && project.getState() != ContinuumProjectState.CHECKEDOUT )
        {
            // Check SCM changes
            allChangesUnknown = checkAllChangesUnknown( context.getScmResult().getChanges() );

            if ( allChangesUnknown )
            {
                if ( !context.getScmResult().getChanges().isEmpty() )
                {
                    getLogger().info(
                        "The project was not built because all changes are unknown (maybe local modifications or ignored files not defined in your SCM tool." );
                }
                else
                {
                    getLogger().info(
                        "The project was not built because no changes were detected in sources since the last build." );
                }
            }

            // Check dependencies changes
            if ( context.getModifiedDependencies() != null && !context.getModifiedDependencies().isEmpty() )
            {
                getLogger().info( "Found dependencies changes, building" );
                shouldBuild = true;
            }
        }

        // Check changes
        if ( !shouldBuild && !allChangesUnknown && !context.getScmResult().getChanges().isEmpty() )
        {
            try
            {
                ContinuumBuildExecutor executor = buildExecutorManager.getBuildExecutor( project.getExecutorId() );
                shouldBuild = executor.shouldBuild( context.getScmResult().getChanges(), project,
                                                    workingDirectoryService.getWorkingDirectory( project ),
                                                    context.getBuildDefinition() );
            }
            catch ( Exception e )
            {
                throw new TaskExecutionException( "Can't determine if the project should build or not", e );
            }
        }

        if ( shouldBuild )
        {
            getLogger().info( "Changes found in the current project, building" );
        }
        else
        {
            project.setState( project.getOldState() );

            project.setOldState( 0 );

            try
            {
                projectDao.updateProject( project );
            }
            catch ( ContinuumStoreException e )
            {
                throw new TaskExecutionException( "Error storing project", e );
            }
            getLogger().info( "No changes in the current project, not building" );

        }

        return shouldBuild;
    }

    private boolean checkAllChangesUnknown( List<ChangeSet> changes )
    {
        for ( ChangeSet changeSet : changes )
        {
            List<ChangeFile> changeFiles = changeSet.getFiles();

            for ( ChangeFile changeFile : changeFiles )
            {
                if ( !"unknown".equalsIgnoreCase( changeFile.getStatus() ) )
                {
                    return false;
                }
            }
        }

        return true;
    }

    private String getValidationMessages( ScmRepositoryException ex )
    {
        List<String> messages = ex.getValidationMessages();

        StringBuffer message = new StringBuffer();

        if ( messages != null && !messages.isEmpty() )
        {
            for ( Iterator<String> i = messages.iterator(); i.hasNext(); )
            {
                message.append( i.next() );

                if ( i.hasNext() )
                {
                    message.append( System.getProperty( "line.separator" ) );
                }
            }
        }
        return message.toString();
    }

    protected void checkProjectDependencies( BuildContext context )
    {
        if ( context.getOldBuildResult() == null )
        {
            return;
        }

        try
        {
            Project project = projectDao.getProjectWithAllDetails( context.getProject().getId() );
            List<ProjectDependency> dependencies = project.getDependencies();

            if ( dependencies == null )
            {
                dependencies = new ArrayList<ProjectDependency>();
            }

            if ( project.getParent() != null )
            {
                dependencies.add( project.getParent() );
            }

            if ( dependencies.isEmpty() )
            {
                return;
            }

            List<ProjectDependency> modifiedDependencies = new ArrayList<ProjectDependency>();

            for ( ProjectDependency dep : dependencies )
            {
                Project dependencyProject =
                    projectDao.getProject( dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );

                if ( dependencyProject != null )
                {
                    List buildResults = buildResultDao.getBuildResultsInSuccessForProject( dependencyProject.getId(),
                                                                                           context.getOldBuildResult().getEndTime() );
                    if ( buildResults != null && !buildResults.isEmpty() )
                    {
                        getLogger().debug( "Dependency changed: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" +
                            dep.getVersion() );
                        modifiedDependencies.add( dep );
                    }
                    else
                    {
                        getLogger().debug( "Dependency not changed: " + dep.getGroupId() + ":" + dep.getArtifactId() +
                            ":" + dep.getVersion() );
                    }
                }
                else
                {
                    getLogger().debug( "Skip non Continuum project: " + dep.getGroupId() + ":" + dep.getArtifactId() +
                        ":" + dep.getVersion() );
                }
            }

            context.setModifiedDependencies( modifiedDependencies );
            context.getActionContext().put( AbstractContinuumAction.KEY_UPDATE_DEPENDENCIES, modifiedDependencies );
        }
        catch ( ContinuumStoreException e )
        {
            getLogger().warn( "Can't get the project dependencies", e );
        }
    }

    private String convertScmResultToError( ScmResult result )
    {
        String error = "";

        if ( result == null )
        {
            error = "Scm result is null.";
        }
        else
        {
            if ( result.getCommandLine() != null )
            {
                error = "Command line: " + StringUtils.clean( result.getCommandLine() ) +
                    System.getProperty( "line.separator" );
            }

            if ( result.getProviderMessage() != null )
            {
                error = "Provider message: " + StringUtils.clean( result.getProviderMessage() ) +
                    System.getProperty( "line.separator" );
            }

            if ( result.getCommandOutput() != null )
            {
                error += "Command output: " + System.getProperty( "line.separator" );
                error += "-------------------------------------------------------------------------------" +
                    System.getProperty( "line.separator" );
                error += StringUtils.clean( result.getCommandOutput() ) + System.getProperty( "line.separator" );
                error += "-------------------------------------------------------------------------------" +
                    System.getProperty( "line.separator" );
            }

            if ( result.getException() != null )
            {
                error += "Exception:" + System.getProperty( "line.separator" );
                error += result.getException();
            }
        }

        return error;
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private BuildResult makeAndStoreBuildResult( BuildContext context, String error )
        throws TaskExecutionException
    {
        // Project project, ScmResult scmResult, long startTime, int trigger )
        // project, scmResult, startTime, trigger );

        BuildResult build = new BuildResult();

        build.setState( ContinuumProjectState.ERROR );

        build.setTrigger( context.getTrigger() );

        build.setStartTime( context.getStartTime() );

        build.setEndTime( System.currentTimeMillis() );

        updateBuildResult( build, context );

        build.setScmResult( context.getScmResult() );

        build.setBuildDefinition( context.getBuildDefinition() );

        if ( error != null )
        {
            build.setError( error );
        }

        try
        {
            buildResultDao.addBuildResult( context.getProject(), build );

            build = buildResultDao.getBuildResult( build.getId() );

            context.setBuildResult( build );

            return build;
        }
        catch ( ContinuumStoreException e )
        {
            throw new TaskExecutionException( "Error storing build result", e );
        }
    }

    private ScmResult getOldScmResults( int projectId, long startId, long fromDate )
        throws ContinuumStoreException
    {
        List<BuildResult> results = buildResultDao.getBuildResultsForProjectFromId( projectId, startId );

        ScmResult res = new ScmResult();

        if ( results != null )
        {
            for ( BuildResult result : results )
            {
                ScmResult scmResult = result.getScmResult();

                if ( scmResult != null )
                {
                    List<ChangeSet> changes = scmResult.getChanges();

                    if ( changes != null )
                    {
                        for ( ChangeSet changeSet : changes )
                        {
                            if ( changeSet.getDate() < fromDate )
                            {
                                continue;
                            }                            
                            if ( !res.getChanges().contains( changeSet ) )
                            {
                                res.addChange( changeSet );
                            }
                        }
                    }
                }
            }
        }

        return res;
    }

    /**
     * Merges scm results so we'll have all changes since last execution of current build definition
     *
     * @param context The build context
     */
    private void mergeScmResults( BuildContext context )
    {
        ScmResult oldScmResult = context.getOldScmResult();
        ScmResult newScmResult = context.getScmResult();

        if ( oldScmResult != null )
        {
            if ( newScmResult == null )
            {
                context.setScmResult( oldScmResult );
            }
            else
            {
                List<ChangeSet> oldChanges = oldScmResult.getChanges();

                List<ChangeSet> newChanges = newScmResult.getChanges();

                for ( ChangeSet change : newChanges )
                {
                    if ( !oldChanges.contains( change ) )
                    {
                        oldChanges.add( change );
                    }
                }

                newScmResult.setChanges( oldChanges );
            }
        }
    }

    /**
     * Check to see if there was a error while checking out/updating the project
     *
     * @param context The build context
     * @return true if scm result is ok
     * @throws TaskExecutionException
     */
    private boolean checkScmResult( BuildContext context )
        throws TaskExecutionException
    {
        ScmResult scmResult = context.getScmResult();

        if ( scmResult == null || !scmResult.isSuccess() )
        {
            // scmResult must be converted before storing it because jpox modifies values of all fields to null
            String error = convertScmResultToError( scmResult );

            BuildResult build = makeAndStoreBuildResult( context, error );

            try
            {
                Project project = context.getProject();

                project.setState( build.getState() );

                projectDao.updateProject( project );

                return false;
            }
            catch ( ContinuumStoreException e )
            {
                throw new TaskExecutionException( "Error storing project", e );
            }
        }

        context.getActionContext().put( AbstractContinuumAction.KEY_UPDATE_SCM_RESULT, scmResult );

        return true;
    }

}
