package org.apache.maven.scm.client.cli;

/*
 * 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.scm.ScmBranch;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFile;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.ScmResult;
import org.apache.maven.scm.ScmRevision;
import org.apache.maven.scm.ScmTag;
import org.apache.maven.scm.ScmVersion;
import org.apache.maven.scm.command.checkin.CheckInScmResult;
import org.apache.maven.scm.command.checkout.CheckOutScmResult;
import org.apache.maven.scm.command.update.UpdateScmResult;
import org.apache.maven.scm.manager.NoSuchScmProviderException;
import org.apache.maven.scm.manager.ScmManager;
import org.apache.maven.scm.repository.ScmRepository;
import org.apache.maven.scm.repository.ScmRepositoryException;
import org.codehaus.plexus.embed.Embedder;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.util.Iterator;
import java.util.List;

/**
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
 * @version $Id$
 */
public class MavenScmCli
{
    private Embedder plexus;

    private ScmManager scmManager;

    // ----------------------------------------------------------------------
    // Lifecycle
    // ----------------------------------------------------------------------

    public MavenScmCli()
        throws Exception
    {
        plexus = new Embedder();

        plexus.start();

        scmManager = (ScmManager) plexus.lookup( ScmManager.ROLE );
    }

    public void stop()
    {
        try
        {
            plexus.stop();
        }
        catch ( Exception ex )
        {
            // ignore
        }
    }

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

    public static void main( String[] args )
    {
        MavenScmCli cli;

        try
        {
            cli = new MavenScmCli();
        }
        catch ( Exception ex )
        {
            System.err.println( "Error while starting Maven Scm." );

            ex.printStackTrace( System.err );

            return;
        }

        String scmUrl;

        String command;

        if ( args.length != 3 )
        {
            System.err.println(
                "Usage: maven-scm-client <command> <working directory> <scm url> [<scmVersion> [<scmVersionType>]]" );
            System.err.println( "scmVersion is a branch name/tag name/revision number." );
            System.err.println( "scmVersionType can be 'branch', 'tag', 'revision'. "
                + "The default value is 'revision'." );

            return;
        }

        command = args[0];

        File workingDirectory = new File( args[1] );

        scmUrl = args[2];

        ScmVersion scmVersion = null;
        if ( args.length > 3 )
        {
            String version = args[3];

            if ( args.length > 4 )
            {
                String type = args[4];

                if ( "tag".equals( type ) )
                {
                    scmVersion = new ScmTag( version );
                }
                else if ( "branch".equals( type ) )
                {
                    scmVersion = new ScmBranch( version );
                }
                else if ( "revision".equals( type ) )
                {
                    scmVersion = new ScmRevision( version );
                }
                else
                {
                    throw new IllegalArgumentException( "'" + type + "' version type isn't known." );
                }
            }
            else
            {
                scmVersion = new ScmRevision( args[3] );
            }
        }

        cli.execute( scmUrl, command, workingDirectory, scmVersion );

        cli.stop();
    }

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

    public void execute( String scmUrl, String command, File workingDirectory, ScmVersion version )
    {
        ScmRepository repository;

        try
        {
            repository = scmManager.makeScmRepository( scmUrl );
        }
        catch ( NoSuchScmProviderException ex )
        {
            System.err.println( "Could not find a provider." );

            return;
        }
        catch ( ScmRepositoryException ex )
        {
            System.err.println( "Error while connecting to the repository" );

            ex.printStackTrace( System.err );

            return;
        }

        try
        {
            if ( command.equals( "checkout" ) )
            {
                checkOut( repository, workingDirectory, version );
            }
            else if ( command.equals( "checkin" ) )
            {
                checkIn( repository, workingDirectory, version );
            }
            else if ( command.equals( "update" ) )
            {
                update( repository, workingDirectory, version );
            }
            else
            {
                System.err.println( "Unknown SCM command '" + command + "'." );
            }
        }
        catch ( ScmException ex )
        {
            System.err.println( "Error while executing the SCM command." );

            ex.printStackTrace( System.err );

            return;
        }
    }

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

    private void checkOut( ScmRepository scmRepository, File workingDirectory, ScmVersion version )
        throws ScmException
    {
        if ( workingDirectory.exists() )
        {
            System.err.println( "The working directory already exist: '" + workingDirectory.getAbsolutePath()
                + "'." );

            return;
        }

        if ( !workingDirectory.mkdirs() )
        {
            System.err.println(
                "Error while making the working directory: '" + workingDirectory.getAbsolutePath() + "'." );

            return;
        }

        CheckOutScmResult result = scmManager.checkOut( scmRepository, new ScmFileSet( workingDirectory ), version );

        if ( !result.isSuccess() )
        {
            showError( result );

            return;
        }

        List checkedOutFiles = result.getCheckedOutFiles();

        System.out.println( "Checked out these files: " );

        for ( Iterator it = checkedOutFiles.iterator(); it.hasNext(); )
        {
            ScmFile file = (ScmFile) it.next();

            System.out.println( " " + file.getPath() );
        }
    }

    private void checkIn( ScmRepository scmRepository, File workingDirectory, ScmVersion version )
        throws ScmException
    {
        if ( !workingDirectory.exists() )
        {
            System.err.println( "The working directory doesn't exist: '" + workingDirectory.getAbsolutePath()
                + "'." );

            return;
        }

        String message = "";

        CheckInScmResult result =
            scmManager.checkIn( scmRepository, new ScmFileSet( workingDirectory ), version, message );

        if ( !result.isSuccess() )
        {
            showError( result );

            return;
        }

        List checkedInFiles = result.getCheckedInFiles();

        System.out.println( "Checked in these files: " );

        for ( Iterator it = checkedInFiles.iterator(); it.hasNext(); )
        {
            ScmFile file = (ScmFile) it.next();

            System.out.println( " " + file.getPath() );
        }
    }

    private void update( ScmRepository scmRepository, File workingDirectory, ScmVersion version )
        throws ScmException
    {
        if ( !workingDirectory.exists() )
        {
            System.err.println( "The working directory doesn't exist: '" + workingDirectory.getAbsolutePath()
                + "'." );

            return;
        }

        UpdateScmResult result = scmManager.update( scmRepository, new ScmFileSet( workingDirectory ), version );

        if ( !result.isSuccess() )
        {
            showError( result );

            return;
        }

        List updatedFiles = result.getUpdatedFiles();

        System.out.println( "Updated these files: " );

        for ( Iterator it = updatedFiles.iterator(); it.hasNext(); )
        {
            ScmFile file = (ScmFile) it.next();

            System.out.println( " " + file.getPath() );
        }
    }

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

    private void showError( ScmResult result )
    {
        System.err.println( "There was a error while executing the SCM command." );

        String providerMessage = result.getProviderMessage();

        if ( !StringUtils.isEmpty( providerMessage ) )
        {
            System.err.println( "Error message from the provider: " + providerMessage );
        }
        else
        {
            System.err.println( "The provider didn't give a error message." );
        }

        String output = result.getCommandOutput();

        if ( !StringUtils.isEmpty( output ) )
        {
            System.err.println( "Command output:" );

            System.err.println( output );
        }
    }
}
