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 )
    {
        if ( url == null || url.length() == 0 )
        {
            return "localhost";
        }
        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;
    }
}
