package org.apache.maven.wagon;

/*
 * 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.StringTokenizer;

/**
 * Various path (URL) manipulation routines
 *
 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
 *
 */
public final class PathUtils
{
    private PathUtils()
    {
    }

    /**
     * Returns the directory path portion of a file specification string.
     * Matches the equally named unix command.
     *
     * @return The directory portion excluding the ending file separator.
     */
    public static String dirname( final String path )
    {
        final int i = path.lastIndexOf( "/" );

        return ( ( i >= 0 ) ? path.substring( 0, i ) : "" );
    }

    /**
     * Returns the filename portion of a file specification string.
     *
     * @return The filename string with extension.
     */
    public static String filename( final String path )
    {
        final int i = path.lastIndexOf( "/" );
        return ( ( i >= 0 ) ? path.substring( i + 1 ) : path );
    }

    public static String[] dirnames( final String path )
    {
        final String dirname = PathUtils.dirname( path );
        return split( dirname, "/", -1 );

    }

    private static String[] split( final String str, final String separator, final int max )
    {
        final StringTokenizer tok;

        if ( separator == null )
        {
            // Null separator means we're using StringTokenizer's default
            // delimiter, which comprises all whitespace characters.
            tok = new StringTokenizer( str );
        }
        else
        {
            tok = new StringTokenizer( str, separator );
        }

        int listSize = tok.countTokens();

        if ( max > 0 && listSize > max )
        {
            listSize = max;
        }

        final String[] list = new String[listSize];

        int i = 0;

        int lastTokenBegin;
        int lastTokenEnd = 0;

        while ( tok.hasMoreTokens() )
        {
            if ( max > 0 && i == listSize - 1 )
            {
                // In the situation where we hit the max yet have
                // tokens left over in our input, the last list
                // element gets all remaining text.
                final String endToken = tok.nextToken();

                lastTokenBegin = str.indexOf( endToken, lastTokenEnd );

                list[i] = str.substring( lastTokenBegin );

                break;

            }
            else
            {
                list[i] = tok.nextToken();

                lastTokenBegin = str.indexOf( list[i], lastTokenEnd );

                lastTokenEnd = lastTokenBegin + list[i].length();
            }

            i++;
        }
        return list;
    }

    /**
     * Return the host name (Removes protocol and path from the URL) E.g: for input
     * <code>http://www.codehause.org</code> this method will return <code>www.apache.org</code>
     *
     * @param url the url
     * @return the host name
     */
    public static String host( final String url )
    {
        String authorization = authorization( url );
        int index = authorization.indexOf( '@' );
        String host = ( index >= 0 ) ? authorization.substring( index + 1 ) : authorization;
        // In case we have IPv6 in the host portion of url
        // we have to remove brackets '[' and ']'
        return ( ( host.charAt( 0 ) == '[' ) && ( host.charAt( host.length() - 1 ) == ']' ) )
                        ? host.substring( 1, host.length() - 1 )
                        : host;
    }

    /**
     * This was changed from private to package local so that it can be unit tested.
     */
    static String authorization( final String url )
    {
        if ( url == null )
        {
            return "localhost";
        }

        final String protocol = PathUtils.protocol( url );

        if ( protocol == null || protocol.equalsIgnoreCase( "file" ) )
        {
            return "localhost";
        }

        String host = url;
        if ( protocol.equalsIgnoreCase( "scm" ) )
        {
            // skip over type
            host = host.substring( host.indexOf( ":", 4 ) + 1 ).trim();
        }

        // skip over protocol
        host = host.substring( host.indexOf( ":" ) + 1 ).trim();
        if ( host.startsWith( "//" ) )
        {
            host = host.substring( 2 );
        }

        int pos = host.indexOf( "/" );

        if ( pos > 0 )
        {
            host = host.substring( 0, pos );
        }

        pos = host.indexOf( '@' );

        pos = ( pos > 0 ) ? endOfHostPosition( host, pos ) : endOfHostPosition( host, 0 );

        if ( pos > 0 )
        {
            host = host.substring( 0, pos );
        }
        return host;
    }

    private static int endOfHostPosition( String host, int pos )
    {
        // if this is IPv6 then it will be in IPv6 Literal Addresses in URL's format
        // see: http://www.ietf.org/rfc/rfc2732.txt
        int endOfIPv6Pos = host.indexOf( ']', pos );
        return ( endOfIPv6Pos > 0 ) ? endOfIPv6Pos + 1 : host.indexOf( ":", pos );
    }

    /**
     * /**
     * Return the protocol name.
     * <br/>
     * E.g: for input
     * <code>http://www.codehause.org</code> this method will return <code>http</code>
     *
     * @param url the url
     * @return the host name
     */
    public static String protocol( final String url )
    {
        final int pos = url.indexOf( ":" );

        if ( pos == -1 )
        {
            return "";
        }
        return url.substring( 0, pos ).trim();
    }

    /**
     * @param url
     * @return the port or {@link WagonConstants#UNKNOWN_PORT} if not existent
     */
    public static int port( String url )
    {

        final String protocol = PathUtils.protocol( url );

        if ( protocol == null || protocol.equalsIgnoreCase( "file" ) )
        {
            return WagonConstants.UNKNOWN_PORT;
        }

        final String authorization = PathUtils.authorization( url );

        if ( authorization == null )
        {
            return WagonConstants.UNKNOWN_PORT;
        }

        if ( protocol.equalsIgnoreCase( "scm" ) )
        {
            // skip over type
            url = url.substring( url.indexOf( ":", 4 ) + 1 ).trim();
        }

        if ( url.regionMatches( true, 0, "file:", 0, 5 ) || url.regionMatches( true, 0, "local:", 0, 6 ) )
        {
            return WagonConstants.UNKNOWN_PORT;
        }

        // skip over protocol
        url = url.substring( url.indexOf( ":" ) + 1 ).trim();
        if ( url.startsWith( "//" ) )
        {
            url = url.substring( 2 );
        }

        int start = authorization.length();

        if ( url.length() > start && url.charAt( start ) == ':' )
        {
            int end = url.indexOf( '/', start );

            if ( end == start + 1 )
            {
                // it is :/
                return WagonConstants.UNKNOWN_PORT;
            }

            if ( end == -1 )
            {
                end = url.length();
            }

            return Integer.parseInt( url.substring( start + 1, end ) );
        }
        else
        {
            return WagonConstants.UNKNOWN_PORT;
        }

    }

    /**
     * Derive the path portion of the given URL.
     * 
     * @param url the repository URL
     * @return the basedir of the repository
     * @todo need to URL decode for spaces?
     */
    public static String basedir( String url )
    {
        String protocol = PathUtils.protocol( url );

        String retValue = null;

        if ( protocol.equalsIgnoreCase( "scm" ) )
        {
            // skip over SCM bits
            if ( url.regionMatches( true, 0, "scm:svn:", 0, 8 ) )
            {
                url = url.substring( url.indexOf( ":", 4 ) + 1 );
                protocol = PathUtils.protocol( url );
            }
        }

        if ( protocol.equalsIgnoreCase( "file" ) )
        {
            retValue = url.substring( protocol.length() + 1 );
            retValue = decode( retValue );
            // special case: if omitted // on protocol, keep path as is
            if ( retValue.startsWith( "//" ) )
            {
                retValue = retValue.substring( 2 );

                if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
                {
                    // special case: if there is a windows drive letter, then keep the original return value
                    retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
                }
                else
                {
                    // Now we expect the host
                    int index = retValue.indexOf( "/" );
                    if ( index >= 0 )
                    {
                        retValue = retValue.substring( index + 1 );
                    }

                    // special case: if there is a windows drive letter, then keep the original return value
                    if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
                    {
                        retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
                    }
                    else if ( index >= 0 )
                    {
                        // leading / was previously stripped
                        retValue = "/" + retValue;
                    }
                }
            }

            // special case: if there is a windows drive letter using |, switch to :
            if ( retValue.length() >= 2 && retValue.charAt( 1 ) == '|' )
            {
                retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
            }
        }
        else
        {
            final String authorization = PathUtils.authorization( url );

            final int port = PathUtils.port( url );

            int pos = 0;

            if ( protocol.equalsIgnoreCase( "scm" ) )
            {
                pos = url.indexOf( ":", 4 ) + 1;
                pos = url.indexOf( ":", pos ) + 1;
            }
            else
            {
                int index = url.indexOf( "://" );
                if ( index != -1 )
                {
                    pos = index + 3;
                }
            }

            pos += authorization.length();

            if ( port != WagonConstants.UNKNOWN_PORT )
            {
                pos = pos + Integer.toString( port ).length() + 1;
            }

            if ( url.length() > pos )
            {
                retValue = url.substring( pos );
                if ( retValue.startsWith( ":" ) )
                {
                    // this is for :/ after the host
                    retValue = retValue.substring( 1 );
                }

                // one module may be allowed in the path in CVS
                retValue = retValue.replace( ':', '/' );
            }
        }

        if ( retValue == null )
        {
            retValue = "/";
        }
        return retValue.trim();
    }

    /**
     * Decodes the specified (portion of a) URL. <strong>Note:</strong> This decoder assumes that ISO-8859-1 is used to
     * convert URL-encoded octets to characters.
     * 
     * @param url The URL to decode, may be <code>null</code>.
     * @return The decoded URL or <code>null</code> if the input was <code>null</code>.
     */
    private static String decode( String url )
    {
        String decoded = url;
        if ( url != null )
        {
            int pos = -1;
            while ( ( pos = decoded.indexOf( '%', pos + 1 ) ) >= 0 )
            {
                if ( pos + 2 < decoded.length() )
                {
                    String hexStr = decoded.substring( pos + 1, pos + 3 );
                    char ch = (char) Integer.parseInt( hexStr, 16 );
                    decoded = decoded.substring( 0, pos ) + ch + decoded.substring( pos + 3 );
                }
            }
        }
        return decoded;
    }

    public static String user( String url )
    {
        String host = authorization( url );
        int index = host.indexOf( '@' );
        if ( index > 0 )
        {
            String userInfo = host.substring( 0, index );
            index = userInfo.indexOf( ':' );
            if ( index > 0 )
            {
                return userInfo.substring( 0, index );
            }
            else if ( index < 0 )
            {
                return userInfo;
            }
        }
        return null;
    }

    public static String password( String url )
    {
        String host = authorization( url );
        int index = host.indexOf( '@' );
        if ( index > 0 )
        {
            String userInfo = host.substring( 0, index );
            index = userInfo.indexOf( ':' );
            if ( index >= 0 )
            {
                return userInfo.substring( index + 1 );
            }
        }
        return null;
    }

    // TODO: move to plexus-utils or use something appropriate from there
    public static String toRelative( File basedir, String absolutePath )
    {
        String relative;

        absolutePath = absolutePath.replace( '\\', '/' );
        String basedirPath = basedir.getAbsolutePath().replace( '\\', '/' );

        if ( absolutePath.startsWith( basedirPath ) )
        {
            relative = absolutePath.substring( basedirPath.length() );
            if ( relative.startsWith( "/" ) )
            {
                relative = relative.substring( 1 );
            }
            if ( relative.length() <= 0 )
            {
                relative = ".";
            }
        }
        else
        {
            relative = absolutePath;
        }

        return relative;
    }
}
