package org.apache.maven.scm.provider.perforce;

/*
 * 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.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashSet;

import org.apache.maven.scm.CommandParameters;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.command.add.AddScmResult;
import org.apache.maven.scm.command.blame.BlameScmResult;
import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
import org.apache.maven.scm.command.checkin.CheckInScmResult;
import org.apache.maven.scm.command.checkout.CheckOutScmResult;
import org.apache.maven.scm.command.diff.DiffScmResult;
import org.apache.maven.scm.command.edit.EditScmResult;
import org.apache.maven.scm.command.login.LoginScmResult;
import org.apache.maven.scm.command.remove.RemoveScmResult;
import org.apache.maven.scm.command.status.StatusScmResult;
import org.apache.maven.scm.command.tag.TagScmResult;
import org.apache.maven.scm.command.unedit.UnEditScmResult;
import org.apache.maven.scm.command.update.UpdateScmResult;
import org.apache.maven.scm.log.ScmLogger;
import org.apache.maven.scm.provider.AbstractScmProvider;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.perforce.command.PerforceInfoCommand;
import org.apache.maven.scm.provider.perforce.command.PerforceWhereCommand;
import org.apache.maven.scm.provider.perforce.command.add.PerforceAddCommand;
import org.apache.maven.scm.provider.perforce.command.blame.PerforceBlameCommand;
import org.apache.maven.scm.provider.perforce.command.changelog.PerforceChangeLogCommand;
import org.apache.maven.scm.provider.perforce.command.checkin.PerforceCheckInCommand;
import org.apache.maven.scm.provider.perforce.command.checkout.PerforceCheckOutCommand;
import org.apache.maven.scm.provider.perforce.command.diff.PerforceDiffCommand;
import org.apache.maven.scm.provider.perforce.command.edit.PerforceEditCommand;
import org.apache.maven.scm.provider.perforce.command.login.PerforceLoginCommand;
import org.apache.maven.scm.provider.perforce.command.remove.PerforceRemoveCommand;
import org.apache.maven.scm.provider.perforce.command.status.PerforceStatusCommand;
import org.apache.maven.scm.provider.perforce.command.tag.PerforceTagCommand;
import org.apache.maven.scm.provider.perforce.command.unedit.PerforceUnEditCommand;
import org.apache.maven.scm.provider.perforce.command.update.PerforceUpdateCommand;
import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
import org.apache.maven.scm.repository.ScmRepositoryException;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.Commandline;

/**
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l </a>
 * @author mperham
 *
 * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="perforce"
 */
public class PerforceScmProvider
    extends AbstractScmProvider
{
    private static final String[] PROTOCOLS = { "tcp", "tcp4", "tcp6", "tcp46", "tcp64", "ssl", "ssl4", "ssl6",
        "ssl46", "ssl64" };

    // ----------------------------------------------------------------------
    // ScmProvider Implementation
    // ----------------------------------------------------------------------

    public boolean requiresEditMode()
    {
        return true;
    }

    public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
        throws ScmRepositoryException
    {
        String protocol = null;
        String path;
        int port = 0;
        String host = null;

        //minimal logic to support perforce protocols in scm url, and keep the next part unchange
        int i0 = scmSpecificUrl.indexOf( delimiter );
        if ( i0 > 0 )
        {
            protocol = scmSpecificUrl.substring( 0, i0 );
            HashSet<String> protocols = new HashSet<String>( Arrays.asList( PROTOCOLS ) );
            if ( protocols.contains( protocol ) )
            {
                scmSpecificUrl = scmSpecificUrl.substring( i0 + 1 );
            }
            else
            {
                protocol = null;
            }
        }

        int i1 = scmSpecificUrl.indexOf( delimiter );
        int i2 = scmSpecificUrl.indexOf( delimiter, i1 + 1 );

        if ( i1 > 0 )
        {
            int lastDelimiter = scmSpecificUrl.lastIndexOf( delimiter );
            path = scmSpecificUrl.substring( lastDelimiter + 1 );
            host = scmSpecificUrl.substring( 0, i1 );

            // If there is tree parts in the scm url, the second is the port
            if ( i2 >= 0 )
            {
                try
                {
                    String tmp = scmSpecificUrl.substring( i1 + 1, lastDelimiter );
                    port = Integer.parseInt( tmp );
                }
                catch ( NumberFormatException ex )
                {
                    throw new ScmRepositoryException( "The port has to be a number." );
                }
            }
        }
        else
        {
            path = scmSpecificUrl;
        }

        String user = null;
        String password = null;
        if ( host != null && host.indexOf( '@' ) > 1 )
        {
            user = host.substring( 0, host.indexOf( '@' ) );
            host = host.substring( host.indexOf( '@' ) + 1 );
        }

        if ( path.indexOf( '@' ) > 1 )
        {
            if ( host != null )
            {
                if ( getLogger().isWarnEnabled() )
                {
                    getLogger().warn(
                                      "Username as part of path is deprecated, the new format is "
                                          + "scm:perforce:[username@]host:port:path_to_repository" );
                }
            }

            user = path.substring( 0, path.indexOf( '@' ) );
            path = path.substring( path.indexOf( '@' ) + 1 );
        }

        return new PerforceScmProviderRepository( protocol, host, port, path, user, password );
    }

    public String getScmType()
    {
        return "perforce";
    }

    /** {@inheritDoc} */
    protected ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
                                            CommandParameters parameters )
        throws ScmException
    {
        PerforceChangeLogCommand command = new PerforceChangeLogCommand();
        command.setLogger( getLogger() );
        return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
    }

    public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceAddCommand command = new PerforceAddCommand();
        command.setLogger( getLogger() );
        return (AddScmResult) command.execute( repository, fileSet, params );
    }

    protected RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceRemoveCommand command = new PerforceRemoveCommand();
        command.setLogger( getLogger() );
        return (RemoveScmResult) command.execute( repository, fileSet, params );
    }

    protected CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceCheckInCommand command = new PerforceCheckInCommand();
        command.setLogger( getLogger() );
        return (CheckInScmResult) command.execute( repository, fileSet, params );
    }

    protected CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
                                          CommandParameters params )
        throws ScmException
    {
        PerforceCheckOutCommand command = new PerforceCheckOutCommand();
        command.setLogger( getLogger() );
        return (CheckOutScmResult) command.execute( repository, fileSet, params );
    }

    protected DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceDiffCommand command = new PerforceDiffCommand();
        command.setLogger( getLogger() );
        return (DiffScmResult) command.execute( repository, fileSet, params );
    }

    protected EditScmResult edit( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceEditCommand command = new PerforceEditCommand();
        command.setLogger( getLogger() );
        return (EditScmResult) command.execute( repository, fileSet, params );
    }

    protected LoginScmResult login( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceLoginCommand command = new PerforceLoginCommand();
        command.setLogger( getLogger() );
        return (LoginScmResult) command.execute( repository, fileSet, params );
    }

    protected StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceStatusCommand command = new PerforceStatusCommand();
        command.setLogger( getLogger() );
        return (StatusScmResult) command.execute( repository, fileSet, params );
    }

    protected TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceTagCommand command = new PerforceTagCommand();
        command.setLogger( getLogger() );
        return (TagScmResult) command.execute( repository, fileSet, params );
    }

    protected UnEditScmResult unedit( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceUnEditCommand command = new PerforceUnEditCommand();
        command.setLogger( getLogger() );
        return (UnEditScmResult) command.execute( repository, fileSet, params );
    }

    protected UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceUpdateCommand command = new PerforceUpdateCommand();
        command.setLogger( getLogger() );
        return (UpdateScmResult) command.execute( repository, fileSet, params );
    }

    protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters params )
        throws ScmException
    {
        PerforceBlameCommand command = new PerforceBlameCommand();
        command.setLogger( getLogger() );
        return (BlameScmResult) command.execute( repository, fileSet, params );
    }

    public static Commandline createP4Command( PerforceScmProviderRepository repo, File workingDir )
    {
        Commandline command = new Commandline();
        command.setExecutable( "p4" );
        if ( workingDir != null )
        {
            // SCM-209
            command.createArg().setValue( "-d" );
            command.createArg().setValue( workingDir.getAbsolutePath() );
        }


        if ( repo.getHost() != null )
        {
            command.createArg().setValue( "-p" );
            String value = "";
            if ( ! StringUtils.isBlank( repo.getProtocol() ) )
            {
                value += repo.getProtocol() + ":";
            }
            value += repo.getHost();
            if ( repo.getPort() != 0 )
            {
                value += ":" + Integer.toString( repo.getPort() );
            }
            command.createArg().setValue( value );
        }

        if ( StringUtils.isNotEmpty( repo.getUser() ) )
        {
            command.createArg().setValue( "-u" );
            command.createArg().setValue( repo.getUser() );
        }

        if ( StringUtils.isNotEmpty( repo.getPassword() ) )
        {
            command.createArg().setValue( "-P" );
            command.createArg().setValue( repo.getPassword() );
        }
        return command;
    }

    public static String clean( String string )
    {
        if ( string.indexOf( " -P " ) == -1 )
        {
            return string;
        }
        int idx = string.indexOf( " -P " ) + 4;
        int end = string.indexOf( ' ', idx );
        return string.substring( 0, idx ) + StringUtils.repeat( "*", end - idx ) + string.substring( end );
    }

    /**
     * Given a path like "//depot/foo/bar", returns the
     * proper path to include everything beneath it.
     * <p/>
     * //depot/foo/bar -> //depot/foo/bar/...
     * //depot/foo/bar/ -> //depot/foo/bar/...
     * //depot/foo/bar/... -> //depot/foo/bar/...
     *
     * @param repoPath
     * @return
     */
    public static String getCanonicalRepoPath( String repoPath )
    {
        if ( repoPath.endsWith( "/..." ) )
        {
            return repoPath;
        }
        else if ( repoPath.endsWith( "/" ) )
        {
            return repoPath + "...";
        }
        else
        {
            return repoPath + "/...";
        }
    }

    private static final String NEWLINE = "\r\n";

    /*
     * Clientspec name can be overridden with the system property below.  I don't
     * know of any way for this code to get access to maven's settings.xml so this
     * is the best I can do.
     *
     * Sample clientspec:

     Client: mperham-mikeperham-dt-maven
     Root: d:\temp\target
     Owner: mperham
     View:
     //depot/sandbox/mperham/tsa/tsa-domain/... //mperham-mikeperham-dt-maven/...
     Description:
     Created by maven-scm-provider-perforce

     */
    public static String createClientspec( ScmLogger logger, PerforceScmProviderRepository repo, File workDir,
                                           String repoPath )
    {
        String clientspecName = getClientspecName( logger, repo, workDir );
        String userName = getUsername( logger, repo );

        String rootDir;
        try
        {
            // SCM-184
            rootDir = workDir.getCanonicalPath();
        }
        catch ( IOException ex )
        {
            //getLogger().error("Error getting canonical path for working directory: " + workDir, ex);
            rootDir = workDir.getAbsolutePath();
        }

        StringBuilder buf = new StringBuilder();
        buf.append( "Client: " ).append( clientspecName ).append( NEWLINE );
        buf.append( "Root: " ).append( rootDir ).append( NEWLINE );
        buf.append( "Owner: " ).append( userName ).append( NEWLINE );
        buf.append( "View:" ).append( NEWLINE );
        buf.append( "\t" ).append( PerforceScmProvider.getCanonicalRepoPath( repoPath ) );
        buf.append( " //" ).append( clientspecName ).append( "/..." ).append( NEWLINE );
        buf.append( "Description:" ).append( NEWLINE );
        buf.append( "\t" ).append( "Created by maven-scm-provider-perforce" ).append( NEWLINE );
        return buf.toString();
    }

    public static final String DEFAULT_CLIENTSPEC_PROPERTY = "maven.scm.perforce.clientspec.name";

    public static String getClientspecName( ScmLogger logger, PerforceScmProviderRepository repo, File workDir )
    {
        String def = generateDefaultClientspecName( logger, repo, workDir );
        // until someone put clearProperty in DefaultContinuumScm.getScmRepository( Project , boolean  )
        String l = System.getProperty( DEFAULT_CLIENTSPEC_PROPERTY, def );
        if ( l == null || "".equals( l.trim() ) )
        {
            return def;
        }
        return l;
    }

    private static String generateDefaultClientspecName( ScmLogger logger, PerforceScmProviderRepository repo,
                                                         File workDir )
    {
        String username = getUsername( logger, repo );
        String hostname;
        String path;
        try
        {
            hostname = InetAddress.getLocalHost().getHostName();
            // [SCM-370][SCM-351] client specs cannot contain forward slashes, spaces and ~; "-" is okay
            path = workDir.getCanonicalPath().replaceAll( "[/ ~]", "-" );
        }
        catch ( UnknownHostException e )
        {
            // Should never happen
            throw new RuntimeException( e );
        }
        catch ( IOException e )
        {
            throw new RuntimeException( e );
        }
        return username + "-" + hostname + "-MavenSCM-" + path;
    }

    private static String getUsername( ScmLogger logger, PerforceScmProviderRepository repo )
    {
        String username = PerforceInfoCommand.getInfo( logger, repo ).getEntry( "User name" );
        if ( username == null )
        {
            // os user != perforce user
            username = repo.getUser();
            if ( username == null )
            {
                username = System.getProperty( "user.name", "nouser" );
            }
        }
        return username;
    }

    /**
     * This is a "safe" method which handles cases where repo.getPath() is
     * not actually a valid Perforce depot location.  This is a frequent error
     * due to branches and directory naming where dir name != artifactId.
     *
     * @param log     the logging object to use
     * @param repo    the Perforce repo
     * @param basedir the base directory we are operating in.  If pom.xml exists in this directory,
     *                this method will verify <pre>repo.getPath()/pom.xml</pre> == <pre>p4 where basedir/pom.xml</pre>
     * @return repo.getPath if it is determined to be accurate.  The p4 where location otherwise.
     */
    public static String getRepoPath( ScmLogger log, PerforceScmProviderRepository repo, File basedir )
    {
        PerforceWhereCommand where = new PerforceWhereCommand( log, repo );

        // Handle an edge case where we release:prepare'd a module with an invalid SCM location.
        // In this case, the release.properties will contain the invalid URL for checkout purposes
        // during release:perform.  In this case, the basedir is not the module root so we detect that
        // and remove the trailing target/checkout directory.
        if ( basedir.toString().replace( '\\', '/' ).endsWith( "/target/checkout" ) )
        {
            String dir = basedir.toString();
            basedir = new File( dir.substring( 0, dir.length() - "/target/checkout".length() ) );
            log.debug( "Fixing checkout URL: " + basedir );
        }
        File pom = new File( basedir, "pom.xml" );
        String loc = repo.getPath();
        log.debug( "SCM path in pom: " + loc );
        if ( pom.exists() )
        {
            loc = where.getDepotLocation( pom );
            if ( loc == null )
            {
                loc = repo.getPath();
                log.debug( "cannot find depot => using " + loc );
            }
            else if ( loc.endsWith( "/pom.xml" ) )
            {
                loc = loc.substring( 0, loc.length() - "/pom.xml".length() );
                log.debug( "Actual POM location: " + loc );
                if ( !repo.getPath().equals( loc ) )
                {
                    log.info( "The SCM location in your pom.xml (" + repo.getPath()
                        + ") is not equal to the depot location (" + loc
                        + ").  This happens frequently with branches.  " + "Ignoring the SCM location." );
                }
            }
        }
        return loc;
    }


    private static Boolean live = null;

    public static boolean isLive()
    {
        if ( live == null )
        {
            if ( !Boolean.getBoolean( "maven.scm.testing" ) )
            {
                // We are not executing in the tests so we are live.
                live = Boolean.TRUE;
            }
            else
            {
                // During unit tests, we need to check the local system
                // to see if the user has Perforce installed.  If not, we mark
                // the provider as "not live" (or dead, I suppose!) and skip
                // anything that requires an active server connection.
                try
                {
                    Commandline command = new Commandline();
                    command.setExecutable( "p4" );
                    Process proc = command.execute();
                    BufferedReader br = new BufferedReader( new InputStreamReader( proc.getInputStream() ) );
                    @SuppressWarnings( "unused" )
                    String line;
                    while ( ( line = br.readLine() ) != null )
                    {
                        //System.out.println(line);
                    }
                    int rc = proc.exitValue();
                    live = ( rc == 0 ? Boolean.TRUE : Boolean.FALSE );
                }
                catch ( Exception e )
                {
                    e.printStackTrace();
                    live = Boolean.FALSE;
                }
            }
        }

        return live.booleanValue();
    }
}
