/*
 *  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.api.ldap.model.name;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;

import org.apache.directory.api.i18n.I18n;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapComparator;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.Normalizer;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.util.Serialize;
import org.apache.directory.api.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * <p>
 * A Attribute Type And Value, which is the basis of all Rdn. It contains a
 * type, and a value. The type must not be case sensitive. Superfluous leading
 * and trailing spaces MUST have been trimmed before. The value MUST be in UTF8
 * format, according to RFC 2253. If the type is in OID form, then the value
 * must be a hexadecimal string prefixed by a '#' character. Otherwise, the
 * string must respect the RC 2253 grammar.
 * </p>
 * <p>
 * We will also keep a User Provided form of the AVA (Attribute Type And Value),
 * called upName.
 * </p>
 * <p>
 * This class is immutable
 * </p>
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class Ava implements Externalizable, Cloneable, Comparable<Ava>
{
    /**
     * Declares the Serial Version Uid.
     *
     * @see <a
     *      href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always
     *      Declare Serial Version Uid</a>
     */
    private static final long serialVersionUID = 1L;

    /** The LoggerFactory used by this class */
    private static final Logger LOG = LoggerFactory.getLogger( Ava.class );

    /** The normalized Name type */
    private String normType;

    /** The user provided Name type */
    private String upType;

    /** The value. It can be a String or a byte array */
    private Value value;

    /** The user provided Ava */
    private String upName;

    /** The attributeType if the Ava is schemaAware */
    private AttributeType attributeType;

    /** the schema manager */
    private transient SchemaManager schemaManager;

    /** The computed hashcode */
    private volatile int h;


    /**
     * Constructs an empty Ava
     */
    public Ava()
    {
        this( null );
    }


    /**
     * Constructs an empty schema aware Ava.
     * 
     * @param schemaManager The SchemaManager instance
     */
    public Ava( SchemaManager schemaManager )
    {
        normType = null;
        upType = null;
        value = null;
        upName = "";
        this.schemaManager = schemaManager;
        attributeType = null;
    }


    /**
     * Constructs new Ava using the provided SchemaManager and AVA
     * 
     * @param schemaManager The SchemaManager instance
     * @param ava The AVA to copy
     * @throws LdapInvalidDnException If the Ava is invalid
     */
    public Ava( SchemaManager schemaManager, Ava ava ) throws LdapInvalidDnException
    {
        upType = ava.upType;
        
        if ( ava.isSchemaAware() )
        {
            normType = ava.normType;
            value = ava.value;
            attributeType = ava.getAttributeType();
        }
        else
        {
            if ( schemaManager != null )
            {
                attributeType = schemaManager.getAttributeType( ava.normType );
                
                if ( attributeType != null )
                {
                    normType = attributeType.getOid();

                    try
                    {
                        value = new Value( attributeType, ava.value );
                    }
                    catch ( LdapInvalidAttributeValueException e )
                    {
                        throw new LdapInvalidDnException( e.getResultCode() );
                    }
                }
                else
                {
                    normType = ava.normType;
                    value = ava.value;
                }
            }
            else
            {
                normType = ava.normType;
                value = ava.value;
            }
        }
        
        upName = getEscaped();

        hashCode();
    }


    /**
     * Construct an Ava containing a binary value.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param upType The User Provided type
     * @param upValue The User Provided binary value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( String upType, byte[] upValue ) throws LdapInvalidDnException
    {
        this( null, upType, upValue );
    }


    /**
     * Construct a schema aware Ava containing a binary value. The AttributeType
     * and value will be normalized accordingly to the given SchemaManager.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager instance
     * @param upType The User Provided type
     * @param upValue The User Provided binary value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( SchemaManager schemaManager, String upType, byte[] upValue ) throws LdapInvalidDnException
    {
        if ( schemaManager != null )
        {
            this.schemaManager = schemaManager;

            try
            {
                attributeType = schemaManager.lookupAttributeTypeRegistry( upType );
            }
            catch ( LdapException le )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                // Do NOT log the message here. The error may be handled and therefore the log message may polute the log files.
                // Let the caller log the exception if needed.
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
            }

            try
            {
                createAva( schemaManager, upType, new Value( attributeType, upValue ) );
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, liave );
            }
        }
        else
        {
            createAva( upType, new Value( upValue ) );
        }
    }


    /**
     * Construct a schema aware Ava containing a binary value. The AttributeType
     * and value will be normalized accordingly to the given SchemaManager.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager instance
     * @param upType The User Provided type
     * @param upName the User Provided AVA
     * @param upValue The User Provided binary value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( SchemaManager schemaManager, String upType, String upName, byte[] upValue ) throws LdapInvalidDnException
    {
        if ( schemaManager != null )
        {
            this.schemaManager = schemaManager;

            try
            {
                attributeType = schemaManager.lookupAttributeTypeRegistry( upType );
            }
            catch ( LdapException le )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                // Do NOT log the message here. The error may be handled and therefore the log message may polute the log files.
                // Let the caller log the exception if needed.
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
            }

            try
            {
                createAva( schemaManager, upType, new Value( attributeType, upValue ) );
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, liave );
            }
        }
        else
        {
            createAva( upType, new Value( upValue ) );
        }
        
        this.upName = upName;
    }


    /**
     * Construct an Ava with a String value.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param upType The User Provided type
     * @param upValue The User Provided String value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( String upType, String upValue ) throws LdapInvalidDnException
    {
        this( null, upType, upValue );
    }


    /**
     * Construct a schema aware Ava with a String value.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager instance
     * @param upType The User Provided type
     * @param upValue The User Provided String value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( SchemaManager schemaManager, String upType, String upValue ) throws LdapInvalidDnException
    {
        if ( schemaManager != null )
        {
            this.schemaManager = schemaManager;

            try
            {
                attributeType = schemaManager.lookupAttributeTypeRegistry( upType );
            }
            catch ( LdapException le )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                // Do NOT log the message here. The error may be handled and therefore the log message may polute the log files.
                // Let the caller log the exception if needed.
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
            }

            try
            {
                createAva( schemaManager, upType, new Value( attributeType, upValue ) );
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, liave );
            }
        }
        else
        {
            createAva( upType, new Value( upValue ) );
        }
    }


    /**
     * Construct a schema aware Ava with a String value.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager instance
     * @param upType The User Provided type
     * @param upName the User provided AVA
     * @param upValue The User Provided String value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    public Ava( SchemaManager schemaManager, String upType, String upName, String upValue ) throws LdapInvalidDnException
    {
        if ( schemaManager != null )
        {
            this.schemaManager = schemaManager;

            try
            {
                attributeType = schemaManager.lookupAttributeTypeRegistry( upType );
            }
            catch ( LdapException le )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
            }

            try
            {
                createAva( schemaManager, upType, new Value( attributeType, upValue ) );
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, liave );
            }
        }
        else
        {
            createAva( upType, new Value( upValue ) );
        }
        
        this.upName = upName;
    }
    
    
    /**
     * Construct an Ava. The type and value are normalized :
     * <ul>
     *   <li> the type is trimmed and lowercased </li>
     *   <li> the value is trimmed </li>
     * </ul>
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolved
     * to an empty string after having trimmed it.
     *
     * @param upType The User Provided type
     * @param normType The normalized type
     * @param value The User Provided value
     * @param upName The User Provided name (may be escaped)
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    // WARNING : The protection level is left unspecified intentionally.
    // We need this method to be visible from the DnParser class, but not
    // from outside this package.
    /* Unspecified protection */Ava( String upType, String normType, Value value, String upName )
        throws LdapInvalidDnException
    {
        this( null, upType, normType, value, upName );
    }
    
    
    /**
     * Construct an Ava. The type and value are normalized :
     * <ul>
     *   <li> the type is trimmed and lowercased </li>
     *   <li> the value is trimmed </li>
     * </ul>
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolved
     * to an empty string after having trimmed it.
     *
     * @param attributeType The AttributeType for this value
     * @param upType The User Provided type
     * @param normType The normalized type
     * @param value The value
     * @param upName The User Provided name (may be escaped)
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    // WARNING : The protection level is left unspecified intentionally.
    // We need this method to be visible from the DnParser class, but not
    // from outside this package.
    /* Unspecified protection */Ava( AttributeType attributeType, String upType, String normType, Value value, String upName )
        throws LdapInvalidDnException
    {
        this.attributeType = attributeType;
        String upTypeTrimmed = Strings.trim( upType );
        String normTypeTrimmed = Strings.trim( normType );

        if ( Strings.isEmpty( upTypeTrimmed ) )
        {
            if ( Strings.isEmpty( normTypeTrimmed ) )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                LOG.error( message );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message );
            }
            else
            {
                // In this case, we will use the normType instead
                this.normType = Strings.lowerCaseAscii( normTypeTrimmed );
                this.upType = normType;
            }
        }
        else if ( Strings.isEmpty( normTypeTrimmed ) )
        {
            // In this case, we will use the upType instead
            this.normType = Strings.lowerCaseAscii( upTypeTrimmed );
            this.upType = upType;
        }
        else
        {
            this.normType = Strings.lowerCaseAscii( normTypeTrimmed );
            this.upType = upType;
        }

        this.value = value;
        this.upName = upName;
        hashCode();
    }


    /**
     * Construct an Ava. The type and value are normalized :
     * <ul>
     *   <li> the type is trimmed and lowercased </li>
     *   <li> the value is trimmed </li>
     * </ul>
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolved
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager
     * @param upType The User Provided type
     * @param normType The normalized type
     * @param value The value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    // WARNING : The protection level is left unspecified intentionally.
    // We need this method to be visible from the DnParser class, but not
    // from outside this package.
    /* Unspecified protection */Ava( SchemaManager schemaManager, String upType, String normType, Value value )
        throws LdapInvalidDnException
    {
        StringBuilder sb = new StringBuilder();

        this.upType = upType;
        this.normType = normType;
        this.value = value;
        
        sb.append( upType );
        sb.append( '=' );
        
        if ( ( value != null ) && ( value.getString() != null ) )
        {
            sb.append( value.getString() );
        }
        
        upName = sb.toString();

        if ( schemaManager != null )
        {
            apply( schemaManager );
        }

        hashCode();
    }


    /**
     * Construct a schema aware Ava. The AttributeType and value will be checked accordingly
     * to the SchemaManager.
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolve
     * to an empty string after having trimmed it.
     *
     * @param schemaManager The SchemaManager instance
     * @param upType The User Provided type
     * @param value The value
     */
    private void createAva( SchemaManager schemaManager, String upType, Value value )
    {
        StringBuilder sb = new StringBuilder();

        normType = attributeType.getOid();
        this.upType = upType;
        this.value = value;
        
        sb.append( upType );
        sb.append( '=' );
        
        if ( value != null )
        {
            sb.append( Rdn.escapeValue( value.getString() ) );
        }
        
        upName = sb.toString();

        hashCode();
    }


    /**
     * Construct an Ava. The type and value are normalized :
     * <ul>
     *   <li> the type is trimmed and lowercased </li>
     *   <li> the value is trimmed </li>
     * </ul>
     * <p>
     * Note that the upValue should <b>not</b> be null or empty, or resolved
     * to an empty string after having trimmed it.
     *
     * @param upType The User Provided type
     * @param upValue The User Provided value
     * 
     * @throws LdapInvalidDnException If the given type or value are invalid
     */
    private void createAva( String upType, Value upValue ) throws LdapInvalidDnException
    {
        String upTypeTrimmed = Strings.trim( upType );
        String normTypeTrimmed = Strings.trim( normType );

        if ( Strings.isEmpty( upTypeTrimmed ) )
        {
            if ( Strings.isEmpty( normTypeTrimmed ) )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                // Do NOT log the message here. The error may be handled and therefore the log message may polute the log files.
                // Let the caller log the exception if needed.
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message );
            }
            else
            {
                // In this case, we will use the normType instead
                this.normType = Strings.lowerCaseAscii( normTypeTrimmed );
                this.upType = normType;
            }
        }
        else if ( Strings.isEmpty( normTypeTrimmed ) )
        {
            // In this case, we will use the upType instead
            this.normType = Strings.lowerCaseAscii( upTypeTrimmed );
            this.upType = upType;
        }
        else
        {
            this.normType = Strings.lowerCaseAscii( normTypeTrimmed );
            this.upType = upType;

        }

        value = upValue;

        upName = getEscaped();
        
        hashCode();
    }


    /**
     * Apply a SchemaManager to the Ava. It will normalize the Ava.<br>
     * If the Ava already had a SchemaManager, then the new SchemaManager will be
     * used instead.
     * 
     * @param schemaManager The SchemaManager instance to use
     * @throws LdapInvalidDnException If the Ava can't be normalized accordingly
     * to the given SchemaManager
     */
    private void apply( SchemaManager schemaManager ) throws LdapInvalidDnException
    {
        if ( schemaManager != null )
        {
            this.schemaManager = schemaManager;

            AttributeType tmpAttributeType = null;

            try
            {
                tmpAttributeType = schemaManager.lookupAttributeTypeRegistry( normType );
            }
            catch ( LdapException le )
            {
                if ( schemaManager.isRelaxed() )
                {
                    // No attribute in the schema, but the schema is relaxed : get out
                    return;
                }
                else
                {
                    String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                    // Do NOT log the message here. The error may be handled and therefore the log message may polute the log files.
                    // Let the caller log the exception if needed.
                    throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
                }
            }

            if ( this.attributeType == tmpAttributeType )
            {
                // No need to normalize again
                return;
            }
            else
            {
                this.attributeType = tmpAttributeType;
            }

            try
            {
                value = new Value( tmpAttributeType, value );
            }
            catch ( LdapException le )
            {
                String message = I18n.err( I18n.ERR_13600_TYPE_IS_NULL_OR_EMPTY );
                throw new LdapInvalidDnException( ResultCodeEnum.INVALID_DN_SYNTAX, message, le );
            }

            hashCode();
        }
    }


    /**
     * Get the normalized type of a Ava
     *
     * @return The normalized type
     */
    public String getNormType()
    {
        return normType;
    }


    /**
     * Get the user provided type of a Ava
     *
     * @return The user provided type
     */
    public String getType()
    {
        return upType;
    }


    /**
     * Get the Value of a Ava
     *
     * @return The value
     */
    public Value getValue()
    {
        return value.clone();
    }


    /**
     * Get the user provided form of this attribute type and value
     *
     * @return The user provided form of this ava
     */
    public String getName()
    {
        return upName;
    }
    
    
    /**
     * @return The Ava as an escaped String
     */
    public String getEscaped()
    {
        StringBuilder sb = new StringBuilder();
        
        sb.append( getType() );
        sb.append( '=' );
        sb.append( value.getEscaped() );
        
        return sb.toString();
    }


    /**
     * Implements the cloning.
     *
     * @return a clone of this object
     */
    @Override
    public Ava clone()
    {
        try
        {
            Ava clone = ( Ava ) super.clone();
            clone.value = value.clone();

            return clone;
        }
        catch ( CloneNotSupportedException cnse )
        {
            throw new Error( I18n.err( I18n.ERR_13621_ASSERTION_FAILURE ), cnse );
        }
    }


    /**
     * Gets the hashcode of this object.
     *
     * @see java.lang.Object#hashCode()
     * @return The instance hash code
     */
    @Override
    public int hashCode()
    {
        if ( h == 0 )
        {
            int hTmp = 37;

            hTmp = hTmp * 17 + ( normType != null ? normType.hashCode() : 0 );
            h = hTmp * 17 + ( value != null ? value.hashCode() : 0 );
        }

        return h;
    }


    /**
     * @see Object#equals(Object)
     */
    @Override
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }

        if ( !( obj instanceof Ava ) )
        {
            return false;
        }

        Ava instance = ( Ava ) obj;

        // Compare the type
        if ( attributeType == null )
        {
            if ( normType == null )
            {
                if ( instance.normType != null )
                {
                    return false;
                }
            }
            else
            {
                if ( !normType.equals( instance.normType ) )
                {
                    return false;
                }
            }
        }
        else
        {
            if ( instance.getAttributeType() == null )
            {
                if ( ( schemaManager != null ) 
                        && !attributeType.equals( schemaManager.getAttributeType( instance.getType() ) ) )
                {
                    return false;
                }
            }
            else if ( !attributeType.equals( instance.getAttributeType() ) )
            {
                return false;
            }
        }

        // Compare the values
        if ( ( value == null ) || value.isNull() )
        {
            return ( instance.value == null ) || instance.value.isNull();
        }
        else
        {
            if ( schemaManager != null )
            {
                if ( ( value.getString() != null ) && value.getString().equals( instance.value.getString() ) )
                {
                    return true;
                }

                if ( attributeType == null )
                {
                    attributeType = schemaManager.getAttributeType( normType );
                }
                
                MatchingRule equalityMatchingRule = attributeType.getEquality();

                if ( equalityMatchingRule != null )
                {
                    Normalizer normalizer = equalityMatchingRule.getNormalizer();
                    
                    try
                    {
                        return equalityMatchingRule.getLdapComparator().compare( normalizer.normalize( value.getString() ),
                            instance.value.getString() ) == 0;
                    }
                    catch ( LdapException le )
                    {
                        // TODO: is this OK? If the comparison is not reliable without normalization then we should throw exception
                        // instead returning false. Returning false may be misleading and the log message can be easily overlooked. 
                        // If the comparison is reliable, this should not really be an error. Maybe use debug or trace instead?
                        LOG.error( I18n.err( I18n.ERR_13620_CANNOT_NORMALIZE_VALUE ), le.getMessage() );
                        return false;
                    }
                }
                else
                {
                    // No Equality MR, use a direct comparison
                    if ( !value.isHumanReadable() )
                    {
                        return Arrays.equals( value.getBytes(), instance.value.getBytes() );
                    }
                    else
                    {
                        return value.getString().equals( instance.value.getString() );
                    }
                }
            }
            else
            {
                return value.equals( instance.value );
            }
        }
    }


    /**
     * Serialize the AVA into a buffer at the given position.
     * 
     * @param buffer The buffer which will contain the serialized Ava
     * @param pos The position in the buffer for the serialized value
     * @return The new position in the buffer
     * @throws IOException Id the serialization failed
     */
    public int serialize( byte[] buffer, int pos ) throws IOException
    {
        if ( Strings.isEmpty( upName )
            || Strings.isEmpty( upType )
            || Strings.isEmpty( normType )
            || ( value.isNull() ) )
        {
            String message;

            if ( Strings.isEmpty( upName ) )
            {
                message = I18n.err( I18n.ERR_13616_CANNOT_SERIALIZE_AVA_UPNAME_NULL );
            }
            else if ( Strings.isEmpty( upType ) )
            {
                message = I18n.err( I18n.ERR_13617_CANNOT_SERIALIZE_AVA_UPTYPE_NULL );
            }
            else if ( Strings.isEmpty( normType ) )
            {
                message = I18n.err( I18n.ERR_13618_CANNOT_SERIALIZE_AVA_NORMTYPE_NULL );
            }
            else
            {
                message = I18n.err( I18n.ERR_13619_CANNOT_SERIALIZE_AVA_VALUE_NULL );
            }

            LOG.error( message );
            throw new IOException( message );
        }

        int length = 0;

        // The upName
        byte[] upNameBytes = null;

        if ( upName != null )
        {
            upNameBytes = Strings.getBytesUtf8( upName );
            length += 1 + 4 + upNameBytes.length;
        }

        // The upType
        byte[] upTypeBytes = null;

        if ( upType != null )
        {
            upTypeBytes = Strings.getBytesUtf8( upType );
            length += 1 + 4 + upTypeBytes.length;
        }

        // Is HR
        length++;

        // The hash code
        length += 4;

        // Check that we will be able to store the data in the buffer
        if ( buffer.length - pos < length )
        {
            throw new ArrayIndexOutOfBoundsException();
        }

        // Write the upName
        if ( upName != null )
        {
            buffer[pos++] = Serialize.TRUE;
            pos = Serialize.serialize( upNameBytes, buffer, pos );
        }
        else
        {
            buffer[pos++] = Serialize.FALSE;
        }

        // Write the upType
        if ( upType != null )
        {
            buffer[pos++] = Serialize.TRUE;
            pos = Serialize.serialize( upTypeBytes, buffer, pos );
        }
        else
        {
            buffer[pos++] = Serialize.FALSE;
        }

        // Write the isHR flag
        if ( value.isHumanReadable() )
        {
            buffer[pos++] = Serialize.TRUE;
        }
        else
        {
            buffer[pos++] = Serialize.FALSE;
        }

        // Write the upValue
        if ( value.isHumanReadable() )
        {
            pos = value.serialize( buffer, pos );
        }

        // Write the hash code
        pos = Serialize.serialize( h, buffer, pos );

        return pos;
    }


    /**
     * Deserialize an AVA from a byte[], starting at a given position
     * 
     * @param buffer The buffer containing the AVA
     * @param pos The position in the buffer
     * @return The new position
     * @throws IOException If the serialized value is not an AVA
     * @throws LdapInvalidAttributeValueException If the serialized AVA is invalid
     */
    public int deserialize( byte[] buffer, int pos ) throws IOException, LdapInvalidAttributeValueException
    {
        if ( ( pos < 0 ) || ( pos >= buffer.length ) )
        {
            throw new ArrayIndexOutOfBoundsException();
        }

        // Read the upName value, if it's not null
        boolean hasUpName = Serialize.deserializeBoolean( buffer, pos );
        pos++;

        if ( hasUpName )
        {
            byte[] wrappedValueBytes = Serialize.deserializeBytes( buffer, pos );
            pos += 4 + wrappedValueBytes.length;
            upName = Strings.utf8ToString( wrappedValueBytes );
        }

        // Read the upType value, if it's not null
        boolean hasUpType = Serialize.deserializeBoolean( buffer, pos );
        pos++;

        if ( hasUpType )
        {
            byte[] upTypeBytes = Serialize.deserializeBytes( buffer, pos );
            pos += 4 + upTypeBytes.length;
            upType = Strings.utf8ToString( upTypeBytes );
        }

        // Update the AtributeType
        if ( schemaManager != null )
        {
            if ( !Strings.isEmpty( upType ) )
            {
                attributeType = schemaManager.getAttributeType( upType );
            }
            else
            {
                attributeType = schemaManager.getAttributeType( normType );
            }
        }

        if ( attributeType != null )
        {
            normType = attributeType.getOid();
        }
        else
        {
            normType = upType;
        }

        // Read the isHR flag
        boolean isHR = Serialize.deserializeBoolean( buffer, pos );
        pos++;

        if ( isHR )
        {
            // Read the upValue
            value = Value.createValue( attributeType );
            pos = value.deserialize( buffer, pos );
        }

        // Read the hashCode
        h = Serialize.deserializeInt( buffer, pos );
        pos += 4;

        return pos;
    }


    /**
     * 
     * An Ava is composed of  a type and a value.
     * The data are stored following the structure :
     * <ul>
     *   <li>
     *     <b>upName</b> The User provided ATAV
     *   </li>
     *   <li>
     *     <b>start</b> The position of this ATAV in the Dn
     *   </li>
     *   <li>
     *     <b>length</b> The ATAV length
     *   </li>
     *   <li>
     *     <b>upType</b> The user Provided Type
     *   </li>
     *   <li>
     *     <b>normType</b> The normalized AttributeType
     *   </li>
     *   <li>
     *     <b>isHR</b> Tells if the value is a String or not
     *   </li>
     * </ul>
     * <br>
     * if the value is a String :
     * <ul>
     *   <li>
     *     <b>value</b> The value
     *   </li>
     * </ul>
     * <br>
     * if the value is binary :
     * <ul>
     *   <li>
     *     <b>valueLength</b>
     *   </li>
     *   <li>
     *     <b>value</b> The value
     *   </li>
     * </ul>
     * 
     * @see Externalizable#readExternal(ObjectInput)
     * 
     * @throws IOException If the Ava can't be written in the stream
     */
    @Override
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        if ( Strings.isEmpty( upName )
            || Strings.isEmpty( upType )
            || Strings.isEmpty( normType )
            || ( value.isNull() ) )
        {
            String message;

            if ( Strings.isEmpty( upName ) )
            {
                message = I18n.err( I18n.ERR_13616_CANNOT_SERIALIZE_AVA_UPNAME_NULL );
            }
            else if ( Strings.isEmpty( upType ) )
            {
                message = I18n.err( I18n.ERR_13617_CANNOT_SERIALIZE_AVA_UPTYPE_NULL );
            }
            else if ( Strings.isEmpty( normType ) )
            {
                message = I18n.err( I18n.ERR_13618_CANNOT_SERIALIZE_AVA_NORMTYPE_NULL );
            }
            else
            {
                message = I18n.err( I18n.ERR_13619_CANNOT_SERIALIZE_AVA_VALUE_NULL );
            }

            LOG.error( message );
            throw new IOException( message );
        }

        if ( upName != null )
        {
            out.writeBoolean( true );
            out.writeUTF( upName );
        }
        else
        {
            out.writeBoolean( false );
        }

        if ( upType != null )
        {
            out.writeBoolean( true );
            out.writeUTF( upType );
        }
        else
        {
            out.writeBoolean( false );
        }

        if ( normType != null )
        {
            out.writeBoolean( true );
            out.writeUTF( normType );
        }
        else
        {
            out.writeBoolean( false );
        }

        boolean isHR = value.isHumanReadable();

        out.writeBoolean( isHR );

        value.writeExternal( out );

        // Write the hashCode
        out.writeInt( h );

        out.flush();
    }


    /**
     * We read back the data to create a new ATAV. The structure
     * read is exposed in the {@link Ava#writeExternal(ObjectOutput)}
     * method
     * 
     * @see Externalizable#readExternal(ObjectInput)
     * 
     * @throws IOException If the Ava can't b written to the stream
     * @throws ClassNotFoundException If we can't deserialize an Ava from the stream
     */
    @Override
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        boolean hasUpName = in.readBoolean();

        if ( hasUpName )
        {
            upName = in.readUTF();
        }

        boolean hasUpType = in.readBoolean();

        if ( hasUpType )
        {
            upType = in.readUTF();
        }

        boolean hasNormType = in.readBoolean();

        if ( hasNormType )
        {
            normType = in.readUTF();
        }

        if ( schemaManager != null )
        {
            if ( !Strings.isEmpty( upType ) )
            {
                attributeType = schemaManager.getAttributeType( upType );
            }
            else
            {
                attributeType = schemaManager.getAttributeType( normType );
            }
        }

        in.readBoolean();

        value = Value.deserialize( attributeType, in );

        h = in.readInt();
    }


    /**
     * Tells if the Ava is schema aware or not.
     * 
     * @return <tt>true</tt> if the Ava is schema aware
     */
    public boolean isSchemaAware()
    {
        return attributeType != null;
    }


    /**
     * @return the attributeType
     */
    public AttributeType getAttributeType()
    {
        return attributeType;
    }


    private int compareValues( Ava that )
    {
        int comp;

        if ( value.isHumanReadable() )
        {
            comp = value.compareTo( that.value );

            return comp;
        }
        else
        {
            byte[] bytes1 = value.getBytes();
            byte[] bytes2 = that.value.getBytes();

            for ( int pos = 0; pos < bytes1.length; pos++ )
            {
                int v1 = bytes1[pos] & 0x00FF;
                int v2 = bytes2[pos] & 0x00FF;

                if ( v1 > v2 )
                {
                    return 1;
                }
                else if ( v2 > v1 )
                {
                    return -1;
                }
            }

            return 0;
        }

    }


    /**
     * @see Comparable#compareTo(Object)
     */
    @Override
    public int compareTo( Ava that )
    {
        if ( that == null )
        {
            return 1;
        }

        int comp;

        if ( schemaManager == null )
        {
            // Compare the ATs
            comp = normType.compareTo( that.normType );

            if ( comp != 0 )
            {
                return comp;
            }

            // and compare the values
            if ( value == null )
            {
                if ( that.value == null )
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                if ( that.value == null )
                {
                    return 1;
                }
                else
                {
                    comp = value.compareTo( ( Value ) that.value );

                    return comp;
                }
            }
        }
        else
        {
            if ( that.schemaManager == null )
            {
                // Problem : we will apply the current Ava SchemaManager to the given Ava
                try
                {
                    that.apply( schemaManager );
                }
                catch ( LdapInvalidDnException lide )
                {
                    return 1;
                }
            }

            // First compare the AT OID
            comp = attributeType.getOid().compareTo( that.attributeType.getOid() );

            if ( comp != 0 )
            {
                return comp;
            }

            // Now, compare the two values using the ordering matchingRule comparator, if any
            MatchingRule orderingMR = attributeType.getOrdering();

            if ( orderingMR != null )
            {
                LdapComparator<Object> comparator = ( LdapComparator<Object> ) orderingMR.getLdapComparator();

                if ( comparator != null )
                {
                    comp = value.compareTo( that.value );

                    return comp;
                }
                else
                {
                    comp = compareValues( that );

                    return comp;
                }
            }
            else
            {
                comp = compareValues( that );

                return comp;
            }
        }
    }
    
    
    /**
     * A String representation of an Ava, as provided by the user.
     *
     * @return A string representing an Ava
     */
    @Override
    public String toString()
    {
        return upName;
    }
}
