/*
 * 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.server.core.entry;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;
import java.util.Comparator;

import javax.naming.NamingException;

import org.apache.directory.shared.ldap.NotImplementedException;
import org.apache.directory.shared.ldap.entry.Value;
import org.apache.directory.shared.ldap.entry.client.ClientBinaryValue;
import org.apache.directory.shared.ldap.schema.AttributeType;
import org.apache.directory.shared.ldap.schema.MatchingRule;
import org.apache.directory.shared.ldap.schema.Normalizer;
import org.apache.directory.shared.ldap.schema.comparators.ByteArrayComparator;
import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A server side schema aware wrapper around a binary attribute value.
 * This value wrapper uses schema information to syntax check values,
 * and to compare them for equality and ordering.  It caches results
 * and invalidates them when the wrapped value changes.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class ServerBinaryValue extends ClientBinaryValue
{
    /** Used for serialization */
    private static final long serialVersionUID = 2L;
    
    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( ServerBinaryValue.class );

    /** used to dynamically lookup the attributeType when/if deserializing */
    //@SuppressWarnings ( { "FieldCanBeLocal", "UnusedDeclaration" } )
    //private final String oid;

    /** reference to the attributeType which is not serialized */
    private transient AttributeType attributeType;

    /** A flag set if the normalized data is different from the wrapped data */
    private transient boolean same;


    // -----------------------------------------------------------------------
    // utility methods
    // -----------------------------------------------------------------------
    /**
     * Utility method to get some logs if an assert fails
     */
    protected String logAssert( String message )
    {
        LOG.error(  message );
        return message;
    }

    
    /**
     *  Check the attributeType member. It should not be null, 
     *  and it should contains a syntax.
     */
    protected String checkAttributeType( AttributeType attributeType )
    {
        try
        {
            if ( attributeType == null )
            {
                return "The AttributeType parameter should not be null";
            }
            
            if ( attributeType.getSyntax() == null )
            {
                return "There is no Syntax associated with this attributeType";
            }

            return null;
        }
        catch ( NamingException ne )
        {
            return "This AttributeType is incorrect";
        }
    }

    
    // -----------------------------------------------------------------------
    // Constructors
    // -----------------------------------------------------------------------
    /**
     * Creates a ServerBinaryValue without an initial wrapped value.
     *
     * @param attributeType the schema type associated with this ServerBinaryValue
     */
    public ServerBinaryValue( AttributeType attributeType )
    {
        super();
        
        if ( attributeType == null )
        {
            throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
        }

        try
        {
            if ( attributeType.getSyntax() == null )
            {
                throw new IllegalArgumentException( "There is no Syntax associated with this attributeType" );
            }

            if ( attributeType.getSyntax().isHumanReadable() )
            {
                LOG.warn( "Treating a value of a human readible attribute {} as binary: ", attributeType.getName() );
            }
        }
        catch( NamingException e )
        {
            LOG.error( "Failed to resolve syntax for attributeType {}", attributeType, e );
        }

        this.attributeType = attributeType;
    }


    /**
     * Creates a ServerBinaryValue with an initial wrapped binary value.
     *
     * @param attributeType the schema type associated with this ServerBinaryValue
     * @param wrapped the binary value to wrap which may be null, or a zero length byte array
     */
    public ServerBinaryValue( AttributeType attributeType, byte[] wrapped )
    {
        this( attributeType );
        this.wrapped = wrapped;
    }


    /**
     * Creates a ServerStringValue with an initial wrapped String value and
     * a normalized value.
     *
     * @param attributeType the schema type associated with this ServerStringValue
     * @param wrapped the value to wrap which can be null
     * @param normalizedValue the normalized value
     */
    /** No protection */ 
    ServerBinaryValue( AttributeType attributeType, byte[] wrapped, byte[] normalizedValue, boolean same, boolean valid )
    {
        super( wrapped );
        this.normalized = true;
        this.attributeType = attributeType;
        this.normalizedValue = normalizedValue;
        this.valid = valid;
        this.same = same;
        //this.oid = attributeType.getOid();
    }


    // -----------------------------------------------------------------------
    // ServerValue<byte[]> Methods
    // -----------------------------------------------------------------------
    public void normalize() throws NamingException
    {
        if ( isNormalized() )
        {
            // Bypass the normalization if it has already been done. 
            return;
        }
        
        if ( getReference() != null )
        {
            Normalizer normalizer = getNormalizer();
    
            if ( normalizer == null )
            {
                normalizedValue = getCopy();
                setNormalized( false );
            }
            else
            {
                normalizedValue = ( byte[] ) normalizer.normalize( getCopy() );
                setNormalized( true );
            }
            
            if ( Arrays.equals( super.getReference(), normalizedValue ) )
            {
                same = true;
            }
            else
            {
                same = false;
            }
        }
        else
        {
            normalizedValue = null;
            same = true;
            setNormalized( false );
        }
    }

    
    /**
     * Gets the normalized (cannonical) representation for the wrapped string.
     * If the wrapped String is null, null is returned, otherwise the normalized
     * form is returned.  If no the normalizedValue is null, then this method
     * will attempt to generate it from the wrapped value: repeated calls to
     * this method do not unnecessarily normalize the wrapped value.  Only changes
     * to the wrapped value result in attempts to normalize the wrapped value.
     *
     * @return a reference to the normalized version of the wrapped value
     */
    public byte[] getNormalizedValueReference()
    {
        if ( isNull() )
        {
            return null;
        }

        if ( !isNormalized() )
        {
            try
            {
                normalize();
            }
            catch ( NamingException ne )
            {
                String message = "Cannot normalize the value :" + ne.getMessage();
                LOG.warn( message );
                normalized = false;
            }
        }

        return normalizedValue;
    }


    /**
     * Gets the normalized (canonical) representation for the wrapped byte[].
     * If the wrapped byte[] is null, null is returned, otherwise the normalized
     * form is returned.  If no the normalizedValue is null, then this method
     * will attempt to generate it from the wrapped value: repeated calls to
     * this method do not unnecessarily normalize the wrapped value.  Only changes
     * to the wrapped value result in attempts to normalize the wrapped value.
     *
     * @return gets the normalized value
     */
    public byte[] getNormalizedValue() 
    {
        if ( isNull() )
        {
            return null;
        }

        if ( !normalized )
        {
            try
            {
                normalize();
            }
            catch ( NamingException ne )
            {
                String message = "Cannot normalize the value :" + ne.getMessage();
                LOG.warn( message );
                normalized = false;
            }
        }

        return normalizedValue;
    }


    /**
     * Gets a direct reference to the normalized representation for the
     * wrapped value of this ServerValue wrapper. Implementations will most
     * likely leverage the attributeType this value is associated with to
     * determine how to properly normalize the wrapped value.
     *
     * @return the normalized version of the wrapped value
     */
    public byte[] getNormalizedValueCopy()
    {
        if ( isNull() )
        {
            return null;
        }

        if ( normalizedValue == null )
        {
            try
            {
                normalize();
            }
            catch ( NamingException ne )
            {
                String message = "Cannot normalize the value :" + ne.getMessage();
                LOG.warn( message );
                normalized = false;
            }
        }

        if ( normalizedValue != null )
        {
            byte[] copy = new byte[ normalizedValue.length ];
            System.arraycopy( normalizedValue, 0, copy, 0, normalizedValue.length );
            return copy;
        }
        else
        {
            return null;
        }
    }


    /**
     * Uses the syntaxChecker associated with the attributeType to check if the
     * value is valid.  Repeated calls to this method do not attempt to re-check
     * the syntax of the wrapped value every time if the wrapped value does not
     * change. Syntax checks only result on the first check, and when the wrapped
     * value changes.
     *
     * @see Value#isValid()
     */
    public final boolean isValid()
    {
        if ( valid != null )
        {
            return valid;
        }

        try
        {
            valid = attributeType.getSyntax().getSyntaxChecker().isValidSyntax( getReference() );
        }
        catch ( NamingException ne )
        {
            String message = "Cannot check the syntax : " + ne.getMessage();
            LOG.error( message );
            valid = false;
        }
        
        return valid;
    }

    
    /**
     * @return Tells if the wrapped value and the normalized value are the same 
     */
    public final boolean isSame()
    {
        return same;
    }
    

    /**
     *
     * @see Value#compareTo(Value)
     * @throws IllegalStateException on failures to extract the comparator, or the
     * normalizers needed to perform the required comparisons based on the schema
     */
    public int compareTo( Value<byte[]> value )
    {
        if ( isNull() )
        {
            if ( ( value == null ) || value.isNull() )
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            if ( ( value == null ) || value.isNull() ) 
            {
                return 1;
            }
        }

        if ( value instanceof ServerBinaryValue )
        {
            ServerBinaryValue binaryValue = ( ServerBinaryValue ) value;

            try
            {
                Comparator<? super Value<byte[]>> comparator = getComparator();
                
                if ( comparator != null )
                {
                    return getComparator().compare( getNormalizedValueReference(), binaryValue.getNormalizedValueReference() );
                }
                else
                {
                    return ByteArrayComparator.INSTANCE.compare( getNormalizedValueReference(), 
                        binaryValue.getNormalizedValueReference() );
                }
            }
            catch ( NamingException e )
            {
                String msg = "Failed to compare normalized values for " + Arrays.toString( getReference() )
                        + " and " + value;
                LOG.error( msg, e );
                throw new IllegalStateException( msg, e );
            }
        }

        String message = "I don't really know how to compare anything other " +
        "than ServerBinaryValues at this point in time.";
        LOG.error( message );
        throw new NotImplementedException( message );
    }


    /**
     * Get the associated AttributeType
     * @return The AttributeType
     */
    public AttributeType getAttributeType()
    {
        return attributeType;
    }


    /**
     * Check if the value is stored into an instance of the given 
     * AttributeType, or one of its ascendant.
     * 
     * For instance, if the Value is associated with a CommonName,
     * checking for Name will match.
     * 
     * @param attributeType The AttributeType we are looking at
     * @return <code>true</code> if the value is associated with the given
     * attributeType or one of its ascendant
     */
    public boolean instanceOf( AttributeType attributeType ) throws NamingException
    {
        if ( this.attributeType.equals( attributeType ) )
        {
            return true;
        }

        return this.attributeType.isDescendantOf( attributeType );
    }


    // -----------------------------------------------------------------------
    // Object Methods
    // -----------------------------------------------------------------------
    /**
     * @see Object#hashCode()
     * @return the instance's hash code 
     */
    public int hashCode()
    {
        // return zero if the value is null so only one null value can be
        // stored in an attribute - the string version does the same
        if ( isNull() )
        {
            return 0;
        }

        return Arrays.hashCode( getNormalizedValueReference() );
    }


    /**
     * Checks to see if this ServerBinaryValue equals the supplied object.
     *
     * This equals implementation overrides the BinaryValue implementation which
     * is not schema aware.
     * @throws IllegalStateException on failures to extract the comparator, or the
     * normalizers needed to perform the required comparisons based on the schema
     */
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }

        if ( ! ( obj instanceof ServerBinaryValue ) )
        {
            return false;
        }

        ServerBinaryValue other = ( ServerBinaryValue ) obj;
        
        if ( !attributeType.equals( other.attributeType ) )
        {
            return false;
        }
        
        if ( isNull() )
        {
            return other.isNull();
        }

        // Shortcut : if the values are equals, no need to compare
        // the normalized values
        if ( Arrays.equals( wrapped, other.get() ) )
        {
            return true;
        }
        else
        {
            try
            {
                Comparator<byte[]> comparator = getComparator();

                // Compare normalized values
                if ( comparator == null )
                {
                    return Arrays.equals( getNormalizedValueReference(), other.getNormalizedValueReference() );
                }
                else
                {
                    return comparator.compare( getNormalizedValueReference(), other.getNormalizedValueReference() ) == 0;
                }
            }
            catch ( NamingException ne )
            {
                return false;
            }
        }
    }


    // -----------------------------------------------------------------------
    // Private Helper Methods (might be put into abstract base class)
    // -----------------------------------------------------------------------
    /**
     * Find a matchingRule to use for normalization and comparison.  If an equality
     * matchingRule cannot be found it checks to see if other matchingRules are
     * available: SUBSTR, and ORDERING.  If a matchingRule cannot be found null is
     * returned.
     *
     * @return a matchingRule or null if one cannot be found for the attributeType
     * @throws NamingException if resolution of schema entities fail
     */
    private MatchingRule getMatchingRule() throws NamingException
    {
        MatchingRule mr = attributeType.getEquality();

        if ( mr == null )
        {
            mr = attributeType.getOrdering();
        }

        if ( mr == null )
        {
            mr = attributeType.getSubstr();
        }

        return mr;
    }


    /**
     * Gets a normalizer using getMatchingRule() to resolve the matchingRule
     * that the normalizer is extracted from.
     *
     * @return a normalizer associated with the attributeType or null if one cannot be found
     * @throws NamingException if resolution of schema entities fail
     */
    private Normalizer getNormalizer() throws NamingException
    {
        MatchingRule mr = getMatchingRule();

        if ( mr == null )
        {
            return null;
        }

        return mr.getNormalizer();
    }


    /**
     * Gets a comparator using getMatchingRule() to resolve the matching
     * that the comparator is extracted from.
     *
     * @return a comparator associated with the attributeType or null if one cannot be found
     * @throws NamingException if resolution of schema entities fail
     */
    private Comparator getComparator() throws NamingException
    {
        MatchingRule mr = getMatchingRule();

        if ( mr == null )
        {
            return null;
        }

        return mr.getComparator();
    }
    
    
    /**
     * @return a copy of the current value
     */
    public ServerBinaryValue clone()
    {
        ServerBinaryValue clone = (ServerBinaryValue)super.clone();
        
        if ( normalizedValue != null )
        {
            clone.normalizedValue = new byte[ normalizedValue.length ];
            System.arraycopy( normalizedValue, 0, clone.normalizedValue, 0, normalizedValue.length );
        }
        
        return clone;
    }


    /**
     * @see Externalizable#writeExternal(ObjectOutput)
     * 
     * We can't use this method for a ServerBinaryValue, as we have to feed the value
     * with an AttributeType object
     */ 
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        throw new IllegalStateException( "Cannot use standard serialization for a ServerStringValue" );
    }
    
    
    /**
     * We will write the value and the normalized value, only
     * if the normalized value is different.
     * 
     * If the value is empty, a flag is written at the beginning with 
     * the value true, otherwise, a false is written.
     * 
     * The data will be stored following this structure :
     *  [length] the wrapped length. Can be -1, if wrapped is null
     *  [value length]
     *  [UP value] if not empty
     *  [normalized] (will be false if the value can't be normalized)
     *  [same] (a flag set to true if the normalized value equals the UP value)
     *  [Norm value] (the normalized value if different from the UP value, and not empty)
     *  
     *  @param out the buffer in which we will stored the serialized form of the value
     *  @throws IOException if we can't write into the buffer
     */
    public void serialize( ObjectOutput out ) throws IOException
    {
        if ( wrapped != null )
        {
            // write a the wrapped length
            out.writeInt( wrapped.length );
            
            // Write the data if not empty
            if ( wrapped.length > 0 )
            {
                // The data
                out.write( wrapped );
                
                // Normalize the data
                try
                {
                    normalize();
                    
                    if ( !normalized )
                    {
                        // We may not have a normalizer. Just get out
                        // after having writen the flag
                        out.writeBoolean( false );
                    }
                    else
                    {
                        // Write a flag indicating that the data has been normalized
                        out.writeBoolean( true );
                        
                        if ( Arrays.equals( getReference(), normalizedValue ) )
                        {
                            // Write the 'same = true' flag
                            out.writeBoolean( true );
                        }
                        else
                        {
                            // Write the 'same = false' flag
                            out.writeBoolean( false );
                            
                            // Write the normalized value length
                            out.write( normalizedValue.length );
                            
                            if ( normalizedValue.length > 0 )
                            {
                                // Write the normalized value if not empty
                                out.write( normalizedValue );
                            }
                        }
                    }
                }
                catch ( NamingException ne )
                {
                    // The value can't be normalized, we don't write the 
                    // normalized value.
                    normalizedValue = null;
                    out.writeBoolean( false );
                }
            }
        }
        else
        {
            // Write -1 indicating that the value is null
            out.writeInt( -1 );
        }
    }

    
    /**
     * @see Externalizable#readExternal(ObjectInput)
     * 
     * We can't use this method for a ServerBinaryValue, as we have to feed the value
     * with an AttributeType object
     */
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        throw new IllegalStateException( "Cannot use standard serialization for a ServerStringValue" );
    }
    

    /**
     * 
     * Deserialize a ServerBinaryValue. 
     *
     * @param in the buffer containing the bytes with the serialized value
     * @throws IOException 
     * @throws ClassNotFoundException
     */
    public void deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // The UP value length
        int wrappedLength = in.readInt();
        
        if ( wrappedLength == -1 )
        {
            // If the value is null, the length will be set to -1
            same = true;
            wrapped = null;
        }
        else if ( wrappedLength == 0 )
        {
             wrapped = StringTools.EMPTY_BYTES;
             same = true;
             normalized = true;
             normalizedValue = wrapped;
        }
        else
        {
            wrapped = new byte[wrappedLength];
            
            // Read the data
            in.readFully( wrapped );
            
            // Check if we have a normalized value
            normalized = in.readBoolean();
            
            if ( normalized )
            {
                // Read the 'same' flag
                same = in.readBoolean();
                
                if ( !same )
                {
                    // Read the normalizedvalue length
                    int normalizedLength = in.readInt();
                
                    if ( normalizedLength > 0 )
                    {
                        normalizedValue = new byte[normalizedLength];
                        
                        // Read the normalized value
                        in.read( normalizedValue, 0, normalizedLength );
                    }
                    else
                    {
                        normalizedValue = StringTools.EMPTY_BYTES;
                    }
                }
                else
                {
                    normalizedValue = new byte[wrappedLength];
                    System.arraycopy( wrapped, 0, normalizedValue, 0, wrappedLength );
                }
            }
        }
    }
}
