package org.apache.maven.scm.provider.git.gitexe.command.status;

/*
 * 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.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.scm.ScmFile;
import org.apache.maven.scm.ScmFileStatus;
import org.apache.maven.scm.log.ScmLogger;
import org.codehaus.plexus.util.cli.StreamConsumer;

/**
 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
 */
public class GitStatusConsumer
    implements StreamConsumer
{

    /**
     * The pattern used to match added file lines
     */
    private static final Pattern ADDED_PATTERN = Pattern.compile( "^A[ M]* (.*)$" );

    /**
     * The pattern used to match modified file lines
     */
    private static final Pattern MODIFIED_PATTERN = Pattern.compile( "^ *M[ M]* (.*)$" );

    /**
     * The pattern used to match deleted file lines
     */
    private static final Pattern DELETED_PATTERN = Pattern.compile( "^ *D * (.*)$" );

    /**
     * The pattern used to match renamed file lines
     */
    private static final Pattern RENAMED_PATTERN = Pattern.compile( "^R  (.*) -> (.*)$" );

    private ScmLogger logger;

    private File workingDirectory;

    /**
     * Entries are relative to working directory, not to the repositoryroot
     */
    private List<ScmFile> changedFiles = new ArrayList<ScmFile>();

    private URI relativeRepositoryPath;
    
    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * Consumer when workingDirectory and repositoryRootDirectory are the same
     * 
     * @param logger the logger
     * @param workingDirectory the working directory
     */
    public GitStatusConsumer( ScmLogger logger, File workingDirectory )
    {
        this.logger = logger;
        this.workingDirectory = workingDirectory;
    }

    /**
     * Assuming that you have to discover the repositoryRoot, this is how you can get the
     * <code>relativeRepositoryPath</code>
     * <pre>
     * URI.create( repositoryRoot ).relativize( fileSet.getBasedir().toURI() )
     * </pre>
     * 
     * @param logger the logger
     * @param workingDirectory the working directory
     * @param relativeRepositoryPath the working directory relative to the repository root
     * @since 1.9
     * @see GitStatusCommand#createRevparseShowPrefix(org.apache.maven.scm.ScmFileSet)
     */
    public GitStatusConsumer( ScmLogger logger, File workingDirectory, URI relativeRepositoryPath )
    {
        this( logger, workingDirectory );
        this.relativeRepositoryPath = relativeRepositoryPath;
    }

    // ----------------------------------------------------------------------
    // StreamConsumer Implementation
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void consumeLine( String line )
    {
        if ( logger.isDebugEnabled() )
        {
            logger.debug( line );
        }
        if ( StringUtils.isEmpty( line ) )
        {
            return;
        }

        ScmFileStatus status = null;

        List<String> files = new ArrayList<String>();
        
        Matcher matcher;
        if ( ( matcher = ADDED_PATTERN.matcher( line ) ).find() )
        {
            status = ScmFileStatus.ADDED;
            files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
        }
        else if ( ( matcher = MODIFIED_PATTERN.matcher( line ) ).find() )
        {
            status = ScmFileStatus.MODIFIED;
            files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
        }
        else if ( ( matcher = DELETED_PATTERN.matcher( line ) ).find() )
        {
            status = ScmFileStatus.DELETED;
            files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
        }
        else if ( ( matcher = RENAMED_PATTERN.matcher( line ) ).find() )
        {
            status = ScmFileStatus.RENAMED;
            files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
            files.add( resolvePath( matcher.group( 2 ), relativeRepositoryPath ) );
            logger.debug( "RENAMED status for line '" + line + "' files added '" + matcher.group( 1 ) + "' '"
                              + matcher.group( 2 ) );
        }
        else
        {
            logger.warn( "Ignoring unrecognized line: " + line );
            return;
        }

        // If the file isn't a file; don't add it.
        if ( !files.isEmpty() && status != null )
        {
            if ( workingDirectory != null )
            {
                if ( status == ScmFileStatus.RENAMED )
                {
                    String oldFilePath = files.get( 0 );
                    String newFilePath = files.get( 1 );
                    if ( isFile( oldFilePath ) )
                    {
                        logger.debug( "file '" + oldFilePath + "' is a file" );
                        return;
                    }
                    else
                    {
                        logger.debug( "file '" + oldFilePath + "' not a file" );
                    }
                    if ( !isFile( newFilePath ) )
                    {
                        logger.debug( "file '" + newFilePath + "' not a file" );
                        return;
                    }
                    else
                    {
                        logger.debug( "file '" + newFilePath + "' is a file" );
                    }
                }
                else if ( status == ScmFileStatus.DELETED )
                {
                    if ( isFile( files.get( 0 ) ) )
                    {
                        return;
                    }
                }
                else
                {
                    if ( !isFile( files.get( 0 ) ) )
                    {
                        return;
                    }
                }
            }

            for ( String file : files )
            {
                changedFiles.add( new ScmFile( file, status ) );
            }
        }
    }

    private boolean isFile( String file )
    {
        File targetFile = new File( workingDirectory, file );
        return targetFile.isFile();
    }

    protected static String resolvePath( String fileEntry, URI path )
    {
        /* Quotes may be included (from the git status line) when an fileEntry includes spaces */
        String cleanedEntry = stripQuotes( fileEntry );
        if ( path != null )
        {
            return resolveURI( cleanedEntry, path ).getPath();
        }
        else
        {
            return cleanedEntry;
        }
    }

    /**
     * 
     * @param fileEntry the fileEntry, must not be {@code null}
     * @param path the path, must not be {@code null}
     * @return
     */
    public static URI resolveURI( String fileEntry, URI path )
    {
        // When using URI.create, spaces need to be escaped but not the slashes, so we can't use
        // URLEncoder.encode( String, String )
        // new File( String ).toURI() results in an absolute URI while path is relative, so that can't be used either.
        return path.relativize( uriFromPath( stripQuotes ( fileEntry ) ) );
    }

    /**
     * Create an URI whose getPath() returns the given path and getScheme() returns null. The path may contain spaces,
     * colons, and other special characters.
     * 
     * @param path the path.
     * @return the new URI
     */
    public static URI uriFromPath( String path )
    {
        try
        {
            if ( path != null && path.indexOf( ':' ) != -1 )
            {
                // prefixing the path so the part preceding the colon does not become the scheme
                String tmp = new URI( null, null, "/x" + path, null ).toString().substring( 2 );
                // the colon is not escaped by default
                return new URI( tmp.replace( ":", "%3A" ) );
            }
            else
            {
                return new URI( null, null, path, null );
            }
        }
        catch ( URISyntaxException x )
        {
            throw new IllegalArgumentException( x.getMessage(), x );
        }
    }

    public List<ScmFile> getChangedFiles()
    {
        return changedFiles;
    }

    /**
     * @param str the (potentially quoted) string, must not be {@code null}
     * @return the string with a pair of double quotes removed (if they existed)
     */
    private static String stripQuotes( String str )
    {
        int strLen = str.length();
        return ( strLen > 0 && str.startsWith( "\"" ) && str.endsWith( "\"" ) ) ? unescape( str.substring( 1, strLen - 1 ) ) : str;
    }
    
    /**
     * Dequote a quoted string generated by git status --porcelain.
     * The leading and trailing quotes have already been removed. 
     * @param fileEntry
     * @return
     */
    private static String unescape( String fileEntry )
    {
        // If there are no escaped characters, just return the input argument
        int pos = fileEntry.indexOf( '\\' );
        if ( pos == -1 )
        {
            return fileEntry;
        }
        
        // We have escaped characters
        byte[] inba = fileEntry.getBytes();
        int inSub = 0;      // Input subscript into fileEntry
        byte[] outba = new byte[fileEntry.length()];
        int outSub = 0;     // Output subscript into outba
        
        while ( true )
        {
            System.arraycopy( inba,  inSub,  outba, outSub, pos - inSub );
            outSub += pos - inSub;
            inSub = pos + 1;
            switch ( (char) inba[inSub++] )
            {
                case '"':
                    outba[outSub++] = '"';
                    break;
                    
                case 'a':
                    outba[outSub++] = 7;        // Bell
                    break;
                    
                case 'b':
                    outba[outSub++] = '\b';
                    break;
                    
                case 't':
                    outba[outSub++] = '\t';
                    break;
                    
                case 'n':
                    outba[outSub++] = '\n';
                    break;
                    
                case 'v':
                    outba[outSub++] = 11;       // Vertical tab
                    break;
                    
                case 'f':
                    outba[outSub++] = '\f';
                    break;
                    
                case 'r':
                    outba[outSub++] = '\f';
                    break;
                    
                case '\\':
                    outba[outSub++] = '\\';
                    break;
                    
                case '0':
                case '1':
                case '2':
                case '3':
                    // This assumes that the octal escape here is valid.
                    byte b = (byte) ( ( inba[inSub - 1] - '0' ) << 6 );
                    b |= (byte) ( ( inba[inSub++] - '0' ) << 3 );
                    b |= (byte) ( inba[inSub++] - '0' );
                    outba[outSub++] = b;
                    break;
                    
                default:
                    //This is an invalid escape in a string.  Just copy it.
                    outba[outSub++] = '\\';
                    inSub--;
                    break;
            }
            pos = fileEntry.indexOf( '\\', inSub);
            if ( pos == -1 )        // No more backslashes; we're done
            {
                System.arraycopy( inba, inSub, outba, outSub, inba.length - inSub );
                outSub += inba.length - inSub;
                break;
            }
        }
        try
        {
            // explicit say UTF-8, otherwise it'll fail at least on Windows cmdline
            return new String(outba, 0, outSub, "UTF-8");
        }
        catch ( UnsupportedEncodingException e )
        {
          throw new RuntimeException( e );    
        }
    }
}
