/*
 *  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.model.entry;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.schema.MutableAttributeTypeImpl;
import org.apache.directory.shared.ldap.model.schema.AbstractLdapComparator;
import org.apache.directory.shared.ldap.model.schema.MatchingRule;
import org.apache.directory.shared.ldap.model.schema.Normalizer;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
import org.apache.directory.shared.ldap.model.schema.SyntaxChecker;
import org.apache.directory.shared.util.StringConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A wrapper around byte[] values in entries.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public abstract class AbstractValue<T> implements Value<T>
{
    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( AbstractValue.class );

    /** reference to the attributeType zssociated with the value */
    protected transient MutableAttributeTypeImpl attributeType;

    /** the wrapped binary value */
    protected T wrappedValue;
    
    /** the canonical representation of the wrapped value */
    protected T normalizedValue;

    /** A flag set when the value has been normalized */
    protected boolean normalized;

    /** cached results of the isValid() method call */
    protected Boolean valid;

    /** A flag set if the normalized data is different from the wrapped data */
    protected boolean same;
    
    /** The computed hashcode. We don't want to compute it each time the hashcode() method is called */
    protected volatile int h;

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public Value<T> clone()
    {
        try
        {
            return (Value<T>)super.clone();
        }
        catch ( CloneNotSupportedException cnse )
        {
            // Do nothing
            return null;
        }
    }
    
    
    /**
     * {@inheritDoc}
     */
    public T getReference()
    {
        return wrappedValue;
    }

    
    /**
     * {@inheritDoc}
     */
    public MutableAttributeTypeImpl getAttributeType()
    {
        return attributeType;
    }

    
    /**
     * {@inheritDoc}
     */
    public void apply( MutableAttributeTypeImpl attributeType )
    {
        if ( this.attributeType != null ) 
        {
            if ( !attributeType.equals( this.attributeType ) )
            {
                String message = I18n.err( I18n.ERR_04476, attributeType.getName(), this.attributeType.getName() );
                LOG.info( message );
                throw new IllegalArgumentException( message );
            }
            else
            {
                return;
            }
        }
        
        // First, check that the value is syntaxically correct
        try
        {
            if ( ! isValid( attributeType.getSyntax().getSyntaxChecker() ) )
            {
                String message = I18n.err( I18n.ERR_04476, attributeType.getName(), this.attributeType.getName() );
                LOG.info( message );
                throw new IllegalArgumentException( message );
            }
        }
        catch ( LdapException le )
        {
            String message = I18n.err( I18n.ERR_04447, le.getLocalizedMessage() );
            LOG.info( message );
            normalized = false;
        }
        
        this.attributeType = attributeType;
        
        try
        {
            normalize();
        }
        catch ( LdapException ne )
        {
            String message = I18n.err( I18n.ERR_04447, ne.getLocalizedMessage() );
            LOG.info( message );
            normalized = false;
        }
        
        h=0;
        hashCode();
    }


    /**
     * 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 LdapException if resolution of schema entities fail
     */
    @SuppressWarnings("unchecked")
    protected final AbstractLdapComparator<T> getLdapComparator() throws LdapException
    {
        if ( attributeType != null )
        {
            MatchingRule mr = getMatchingRule();
    
            if ( mr == null )
            {
                return null;
            }
    
            return (AbstractLdapComparator<T>)mr.getLdapComparator();
        }
        else
        {
            return null;
        }
    }
    
    
    /**
     * 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 LdapException if resolution of schema entities fail
     */
    protected final MatchingRule getMatchingRule() throws LdapException
    {
        if ( attributeType != null )
        {
            MatchingRule mr = attributeType.getEquality();
    
            if ( mr == null )
            {
                mr = attributeType.getOrdering();
            }
    
            if ( mr == null )
            {
                mr = attributeType.getSubstring();
            }
    
            return mr;
        }
        else
        {
            return null;
        }
    }


    /**
     * 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 LdapException if resolution of schema entities fail
     */
    protected final Normalizer getNormalizer() throws LdapException
    {
        if ( attributeType != null )
        {
            MatchingRule mr = getMatchingRule();
    
            if ( mr == null )
            {
                return null;
            }
    
            return mr.getNormalizer();
        }
        else
        {
            return null;
        }
    }

    
    /**
     * {@inheritDoc}
     */
    public boolean instanceOf( MutableAttributeTypeImpl attributeType ) throws LdapException
    {
        if ( ( attributeType != null ) && this.attributeType.equals( attributeType ) )
        {
            if ( this.attributeType.equals( attributeType ) )
            {
                return true;
            }
            
            return this.attributeType.isDescendantOf( attributeType );
        }

        return false;
    }


    /**
     * {@inheritDoc}
     */
    public T getNormalizedValueReference()
    {
        if ( isNull() )
        {
            return null;
        }

        if ( normalizedValue == null )
        {
            return wrappedValue;
        }

        return normalizedValue;

    }

    
    /**
     * {@inheritDoc}
     */
    public final boolean isNull()
    {
        return wrappedValue == null; 
    }
    
    
    /**
     * This method is only used for serialization/deserialization
     * 
     * @return Tells if the wrapped value and the normalized value are the same 
     */
    /* no qualifier */ final boolean isSame()
    {
        return same;
    }

    
    /**
     * {@inheritDoc}
     */
    public final boolean isValid()
    {
        if ( valid != null )
        {
            return valid;
        }

        if ( attributeType != null )
        {
            SyntaxChecker syntaxChecker = attributeType.getSyntax().getSyntaxChecker();
            T value = getNormalizedValue();
            valid = syntaxChecker.isValidSyntax( value );
        }
        else
        {
            valid = false;
        }
        
        return valid;
    }
    
    
    /**
     * {@inheritDoc}
     */
    public final boolean isValid( SyntaxChecker syntaxChecker ) throws LdapException
    {
        if ( syntaxChecker == null )
        {
            String message = I18n.err( I18n.ERR_04139, toString() );
            LOG.error( message );
            throw new LdapException( message );
        }
        
        valid = syntaxChecker.isValidSyntax( getReference() );
        
        return valid;
    }


    /**
     * {@inheritDoc}
     */
    public void normalize() throws LdapException
    {
        normalized = true;
        normalizedValue = wrappedValue;
        h = 0;
        hashCode();
    }


    /**
     * {@inheritDoc}
     */
    public final boolean isNormalized()
    {
        return normalized;
    }

    
    /**
     * {@inheritDoc}
     */
    public final void setNormalized( boolean normalized )
    {
        this.normalized = normalized;
    }


    /**
     * Serializes a Value instance.
     * 
     * @param value The Value instance to serialize
     * @param out The stream into which we will write the serialized instance
     * @throws IOException If the stream can't be written
     */
    @SuppressWarnings("unchecked")
    public static void serialize( Value<?> value, ObjectOutput out ) throws IOException
    {
        // The Value type
        out.writeBoolean( value.isBinary() );

        // The AttributeType's OID if we have one
        if ( value.getAttributeType() != null )
        {
            out.writeBoolean( true );
            out.writeUTF( value.getAttributeType().getOid() );
        }
        else
        {
            out.writeBoolean( false );
        }
        
        // The UP value and norm value
        if ( value.isBinary() )
        {
            byte[] upValue = (byte[])value.getReference();
            
            if ( upValue == null )
            {
                out.writeInt( -1 );
            }
            else
            {
                out.writeInt( upValue.length );
                
                if ( upValue.length > 0 )
                {
                    out.write( upValue );
                }
            }

            byte[] normValue = (byte[])value.getNormalizedValueReference();
            
            if ( normValue == null )
            {
                out.writeInt( -1 );
            }
            else
            {
                out.writeInt( normValue.length );
                
                if ( normValue.length > 0 )
                {
                    out.write( normValue );
                }
            }
        }
        else
        {
            if ( ((AbstractValue<String>)value).wrappedValue != null )
            {
                out.writeBoolean( true );
                out.writeUTF( ((AbstractValue<String>)value).wrappedValue );
            }
            else
            {
                out.writeBoolean( false );
            }
            
            if ( ((AbstractValue<String>)value).normalizedValue != null )
            {
                out.writeBoolean( true );
                out.writeUTF( ((AbstractValue<String>)value).normalizedValue );
            }
            else
            {
                out.writeBoolean( false );
            }
        }
        
        // The normalized flag
        out.writeBoolean( value.isNormalized() );
        
        // The valid flag
        out.writeBoolean( value.isValid() );
        
        // The same flag
        if ( value.isBinary() )
        {   
            out.writeBoolean( ((BinaryValue)value).isSame() );
        }
        else
        {
            out.writeBoolean( ((StringValue)value).isSame() );
        }

        // The computed hashCode
        out.writeInt( value.hashCode() );
        
        out.flush();
    }


    /**
     * Deserializes a Value instance.
     * 
     * @param schemaManager The schemaManager instance
     * @param in The input stream from which the Value is read
     * @return a deserialized Value
     * @throws IOException If the stream can't be read
     */
    @SuppressWarnings("unchecked")
    public static Value<?> deserialize( SchemaManager schemaManager, ObjectInput in ) throws IOException
    {
        // The value type
        boolean isBinary = in.readBoolean();
        
        Value<?> value = null;

        if ( isBinary )
        {
            value = new BinaryValue();
        }
        else
        {
            value = new StringValue();
        }

        // The attributeType presence's flag
        boolean hasAttributeType = in.readBoolean();
        
        if ( hasAttributeType )
        {
            String oid = in.readUTF();
            
            if ( schemaManager != null )
            {
                ((AbstractValue<?>)value).attributeType = schemaManager.getAttributeType( oid );
            }
        }
        
        if ( isBinary )
        {
            int upValueSize = in.readInt();
            
            switch ( upValueSize )
            {
                case -1 :
                    break;
                    
                case 0 :
                    ((AbstractValue<byte[]>)value).wrappedValue = StringConstants.EMPTY_BYTES;
                    break;
                    
                default :
                    ((AbstractValue<byte[]>)value).wrappedValue = new byte[upValueSize];
                    in.read( ((AbstractValue<byte[]>)value).wrappedValue );
                    break;
            }

            int normValueSize = in.readInt();
            
            switch ( normValueSize )
            {
                case -1 :
                    break;
                    
                case 0 :
                    ((AbstractValue<byte[]>)value).normalizedValue = StringConstants.EMPTY_BYTES;
                    break;
                   
                default :
                    ((AbstractValue<byte[]>)value).normalizedValue = new byte[normValueSize];
                    in.read( ((AbstractValue<byte[]>)value).normalizedValue );
                    break;
            }
        }
        else
        {
            boolean notNull = in.readBoolean();
            
            if ( notNull )
            {
                ((AbstractValue<String>)value).wrappedValue = in.readUTF();
            }

            notNull = in.readBoolean();
            
            if ( notNull )
            {
                ((AbstractValue<String>)value).normalizedValue = in.readUTF();
            }
        }

        // The normalized flag
        ((AbstractValue<?>)value).normalized = in.readBoolean();
        
        // The valid flag
        ((AbstractValue<?>)value).valid = in.readBoolean();
        
        // The same flag
        ((AbstractValue<?>)value).same = in.readBoolean();

        // The computed hashCode
        ((AbstractValue<?>)value).h = in.readInt();
        
        return value;
    }
}