package org.apache.maven.continuum.execution;

/*
 * 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 java.io.File;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.continuum.utils.shell.ExecutionResult;
import org.apache.continuum.utils.shell.ShellCommandHelper;
import org.apache.maven.continuum.configuration.ConfigurationService;
import org.apache.maven.continuum.configuration.DefaultConfigurationService;
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.utils.ChrootJailWorkingDirectoryService;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.jmock.Expectations;
import org.jmock.Mockery;

public class ContinuumBuildExecutorTest
    extends TestCase
{
    protected AbstractBuildExecutor executor = new BuildExecutorStub();

    private Mockery context = new Mockery();

    private String toSystemPath( String path )
    {
        if ( File.separator.equals( "\\" ) )
        {
            String newPath = path.replaceAll( "/", "\\" + File.separator );
            return newPath.replaceAll( "\\\\bin\\\\sh", "/bin/sh" );
        }
        return path;
    }

    public void testExecuteShellCommand()
        throws Exception
    {
        final File chrootJailFile = new File( toSystemPath( "/home" ) );
        final File workingDirectory = new File( toSystemPath( "/dir1/dir2/workingdir" ) );

        final ShellCommandHelper helper = context.mock( ShellCommandHelper.class );

        ConfigurationService configurationService = new DefaultConfigurationService()
        {
            @Override
            public File getWorkingDirectory()
            {
                return workingDirectory;
            }
        };

        ChrootJailWorkingDirectoryService directoryService = new ChrootJailWorkingDirectoryService();
        directoryService.setConfigurationService( configurationService );
        directoryService.setChrootJailDirectory( chrootJailFile );

        executor.setChrootJailDirectory( chrootJailFile );
        executor.setShellCommandHelper( helper );
        executor.setWorkingDirectoryService( directoryService );
        //executor.enableLogging( new ConsoleLogger( Logger.LEVEL_DEBUG, "" ) );

        final Project project = new Project();
        project.setId( 7 );
        project.setGroupId( "xx" );
        ProjectGroup projectGroup = new ProjectGroup();
        projectGroup.setGroupId( project.getGroupId() );
        project.setProjectGroup( projectGroup );

        assertEquals( toSystemPath( chrootJailFile.getPath() + "/" + project.getGroupId() + workingDirectory.getPath() +
            "/" + project.getId() ), directoryService.getWorkingDirectory( project ).getPath() );

        String executable = "mvn";
        final String arguments = "-o clean install";
        final File output = new File( "target/tmp" );
        final Map<String, String> environments = new HashMap<String, String>();

        final String cmd =
            "chroot /home/xx " + " /bin/sh -c 'cd /dir1/dir2/workingdir/" + project.getId() + " && " + executable +
                " " + arguments + "'";

        final ExecutionResult result = new ExecutionResult( 0 );

        context.checking( new Expectations()
        {
            {
                one( helper ).executeShellCommand( chrootJailFile, "sudo", toSystemPath( cmd ), output,
                                                   project.getId(), environments );
                will( returnValue( result ) );
            }
        } );

        executor.executeShellCommand( project, executable, arguments, output, environments );

        context.assertIsSatisfied();
    }

    class BuildExecutorStub
        extends AbstractBuildExecutor
    {

        protected BuildExecutorStub()
        {
            super( "stub", true );
        }

        protected String findExecutable( Project project, String executable, String defaultExecutable,
                                         boolean resolveExecutable, File workingDirectory )
        {
            return executable;
        }

        @Override
        protected Map<String, String> getEnvironments( BuildDefinition buildDefinition )
        {
            // TODO Auto-generated method stub
            return null;
        }

        public ContinuumBuildExecutionResult build( Project project, BuildDefinition buildDefinition, File buildOutput )
            throws ContinuumBuildExecutorException
        {
            // TODO Auto-generated method stub
            return null;
        }

        public void updateProjectFromCheckOut( File workingDirectory, Project project, BuildDefinition buildDefinition )
            throws ContinuumBuildExecutorException
        {
            // TODO Auto-generated method stub

        }
    }
}
