/*
 *  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. 
 *  
 */
package org.apache.directory.shared.ldap.util;


import java.util.ArrayList;
import java.util.List;

import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
import org.apache.directory.shared.ldap.name.DN;


/**
 * Tools dealing with common Naming operations.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Revision$
 */
public class NamespaceTools
{
    private static final String[] EMPTY_STRING_ARRAY = new String[0];

    
    /**
     * Gets the attribute of a single attribute rdn or name component.
     * 
     * @param rdn the name component
     * @return the attribute name TODO the name rdn is misused rename refactor
     *         this method
     */
    public static String getRdnAttribute( String rdn )
    {
        int index = rdn.indexOf( '=' );
        return rdn.substring( 0, index );
    }


    /**
     * Gets the value of a single name component of a distinguished name.
     * 
     * @param rdn the name component to get the value from
     * @return the value of the single name component TODO the name rdn is
     *         misused rename refactor this method
     */
    public static String getRdnValue( String rdn )
    {
        int index = rdn.indexOf( '=' );
        return rdn.substring( index + 1, rdn.length() );
    }


    /**
     * Checks to see if two names are siblings.
     * 
     * @param name1 the first name
     * @param name2 the second name
     * @return true if the names are siblings, false otherwise.
     */
    public static boolean isSibling( DN name1, DN name2 ) throws LdapInvalidDnException
    {
        if ( name1.size() == name2.size() )
        {
            DN parentDn = ( DN ) name1.clone();
            parentDn.remove( name1.size() - 1 );
            return name2.isChildOf( parentDn );
        }

        return false;
    }


    /**
     * Tests to see if a candidate entry is a descendant of a base.
     * 
     * @param ancestor the base ancestor
     * @param descendant the candidate to test for descendancy
     * @return true if the candidate is a descendant
     */
    public static boolean isDescendant( DN ancestor, DN descendant )
    {
        return descendant.isChildOf( ancestor );
    }


    /**
     * Gets the relative name between an ancestor and a potential descendant.
     * Both name arguments must be normalized. The returned name is also
     * normalized.
     * 
     * @param ancestor the normalized distinguished name of the ancestor context
     * @param descendant the normalized distinguished name of the descendant context
     * @return the relative normalized name between the ancestor and the
     *         descendant contexts
     * @throws LdapInvalidDnException if the contexts are not related in the ancestual sense
     */
    public static DN getRelativeName( DN ancestor, DN descendant ) throws LdapInvalidDnException
    {
        DN rdn = null;
        
        if ( descendant instanceof DN )
        {
            rdn = ( DN ) descendant.clone();
        }
        else
        {
            rdn = new DN( descendant.toString() );
        }

        if ( rdn.isChildOf( ancestor ) )
        {
            for ( int ii = 0; ii < ancestor.size(); ii++ )
            {
                rdn.remove( 0 );
            }
        }
        else
        {
            LdapInvalidDnException e = new LdapInvalidDnException( I18n.err( I18n.ERR_04417, descendant, ancestor ) );

            throw e;
        }

        return rdn;
    }


    /**
     * Uses the algorithm in <a href="http://www.faqs.org/rfcs/rfc2247.html">RFC
     * 2247</a> to infer an LDAP name from a Kerberos realm name or a DNS
     * domain name.
     * 
     * @param realm the realm or domain name
     * @return the LDAP name for the realm or domain
     */
    public static String inferLdapName( String realm )
    {
        if ( StringTools.isEmpty( realm ) )
        {
            return "";
        }

        StringBuffer buf = new StringBuffer( realm.length() );
        buf.append( "dc=" );

        int start = 0, end = 0;

        // Replace all the '.' by ",dc=". The comma is added because
        // the string is not supposed to start with a dot, so another
        // dc=XXXX already exists in any cases.
        // The realm is also not supposed to finish with a '.'
        while ( ( end = realm.indexOf( '.', start ) ) != -1 )
        {
            buf.append( realm.substring( start, end ) ).append( ",dc=" );
            start = end + 1;

        }

        buf.append( realm.substring( start ) );
        return buf.toString();
    }


    /**
     * Gets the '+' appended components of a composite name component.
     * 
     * @param compositeNameComponent a single name component not a whole name
     * @return the components of the complex name component in order
     * @throws LdapInvalidDnException
     *             if nameComponent is invalid (starts with a +)
     */
    public static String[] getCompositeComponents( String compositeNameComponent ) throws LdapInvalidDnException
    {
        int lastIndex = compositeNameComponent.length() - 1;
        List<String> comps = new ArrayList<String>();

        for ( int ii = compositeNameComponent.length() - 1; ii >= 0; ii-- )
        {
            if ( compositeNameComponent.charAt( ii ) == '+' )
            {
                if ( ii == 0 )
                {
                    throw new LdapInvalidDnException( I18n.err( I18n.ERR_04418, compositeNameComponent ) );
                }
                
                if ( compositeNameComponent.charAt( ii - 1 ) != '\\' )
                {
                    if ( lastIndex == compositeNameComponent.length() - 1 )
                    {
                        comps.add( 0, compositeNameComponent.substring( ii + 1, lastIndex + 1 ) );
                    }
                    else
                    {
                        comps.add( 0, compositeNameComponent.substring( ii + 1, lastIndex ) );
                    }

                    lastIndex = ii;
                }
            }
            
            if ( ii == 0 )
            {
                if ( lastIndex == compositeNameComponent.length() - 1 )
                {
                    comps.add( 0, compositeNameComponent );
                }
                else
                {
                    comps.add( 0, compositeNameComponent.substring( ii, lastIndex ) );
                }

                lastIndex = 0;
            }
        }

        if ( comps.size() == 0 )
        {
            comps.add( compositeNameComponent );
        }

        return comps.toArray( EMPTY_STRING_ARRAY );
    }


    /**
     * Checks to see if a name has name complex name components in it.
     * 
     * @param name The name to check 
     * @return <code>true</code> if the name has composite components
     * @throws LdapInvalidDnException If the name is invalid
     */
    public static boolean hasCompositeComponents( String name ) throws LdapInvalidDnException
    {
        for ( int ii = name.length() - 1; ii >= 0; ii-- )
        {
            if ( name.charAt( ii ) == '+' )
            {
                if ( ii == 0 )
                {
                    throw new LdapInvalidDnException( I18n.err( I18n.ERR_04418, name ) );
                }
                if ( name.charAt( ii - 1 ) != '\\' )
                {
                    return true;
                }
            }
        }

        return false;
    }
}
