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


import org.apache.directory.shared.ldap.message.Referral;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;



/**
 * A Referral implementation. For the time being this implementation uses a
 * String representation for LDAPURLs. In the future an LdapUrl interface with
 * default implementations will be used once a parser for an LdapUrl is created.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class ReferralImpl implements Referral
{
    static final long serialVersionUID = 2638820668325359096L;

    /** Sequence of LDAPUrls composing this Referral */
    private final List<String> urls = new ArrayList<String>();

    /** The encoded LdapURL */
    private final List<byte[]> urlsBytes = new ArrayList<byte[]>();

    /** The length of the referral */
    private int referralLength;


    // ------------------------------------------------------------------------
    // LdapResult Interface Method Implementations
    // ------------------------------------------------------------------------
    /**
     * {@inheritDoc}
     */
    public int getReferralLength()
    {
        return referralLength;
    }


    /**
     * {@inheritDoc}
     */
    public void setReferralLength( int referralLength )
    {
        this.referralLength = referralLength;
    }


    /**
     * Gets an unmodifiable set of alternative referral urls.
     * 
     * @return the alternative url objects.
     */
    public Collection<String> getLdapUrls()
    {
        return Collections.unmodifiableCollection( urls );
    }


    /**
     * {@inheritDoc}
     */
    public Collection<byte[]> getLdapUrlsBytes()
    {
        return urlsBytes;
    }


    /**
     * Adds an LDAPv3 URL to this Referral.
     * 
     * @param url the LDAPv3 URL to add
     */
    public void addLdapUrl( String url )
    {
        urls.add( url );
    }


    /**
     * {@inheritDoc}
     */
    public void addLdapUrlBytes( byte[] urlBytes )
    {
        urlsBytes.add( urlBytes );
    }


    /**
     * Removes an LDAPv3 URL to this Referral.
     * 
     * @param url
     *            the LDAPv3 URL to remove
     */
    public void removeLdapUrl( String url )
    {
        urls.remove( url );
    }


    /**
     * @see Object#hashCode()
     * @return the instance's hash code 
     */
    public int hashCode()
    {
        int hash = 37;
        hash = hash * 17 + urls.size();

        // Order doesn't matter, so just add the url hashCode
        for ( String url : urls )
        {
            hash = hash + url.hashCode();
        }

        return hash;
    }


    /**
     * Compares this Referral implementation to see if it is the same as
     * another. The classes do not have to be the same implementation to return
     * true. Both this and the compared Referral must have the same entries
     * exactly. The order of Referral URLs does not matter.
     * 
     * @param obj
     *            the object to compare this ReferralImpl to
     * @return true if both implementations contain exactly the same URLs
     */
    public boolean equals( Object obj )
    {
        // just in case for speed return true if obj is this object
        if ( obj == this )
        {
            return true;
        }

        if ( obj instanceof Referral )
        {
            Collection<String> refs = ( ( Referral ) obj ).getLdapUrls();

            // if their sizes do not match they are not equal
            if ( refs.size() != urls.size() )
            {
                return false;
            }

            Iterator<String> list = urls.iterator();

            while ( list.hasNext() )
            {
                // if one of our urls is not contained in the obj return false
                if ( !refs.contains( list.next() ) )
                {
                    return false;
                }
            }

            // made it through the checks so we have a match
            return true;
        }

        return false;
    }


    /**
     * Get a String representation of a Referral
     * 
     * @return A Referral String
     */
    public String toString()
    {
        StringBuffer sb = new StringBuffer();

        if ( ( urls != null ) && ( urls.size() != 0 ) )
        {
            sb.append( "            Referrals :\n" );

            Object[] urlsArray = urls.toArray();

            for ( int i = 0; i < urlsArray.length; i++ )
            {

                String referral = ( String ) urlsArray[i];

                sb.append( "                Referral[" ).append( i ).append( "] :" ).append( referral ).append( '\n' );
            }
        }

        return sb.toString();
    }
}
