/*
 * 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.Normalizer;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
import org.apache.directory.shared.util.Strings;
import org.apache.directory.shared.util.Unicode;
import org.apache.directory.shared.util.exception.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A server side schema aware wrapper around a String 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>
 */
public class StringValue extends AbstractValue<String>
{
    /** 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( StringValue.class );

    // -----------------------------------------------------------------------
    // Constructors
    // -----------------------------------------------------------------------
    /**
     * Creates a StringValue without an initial wrapped value.
     */
    public StringValue()
    {
        normalized = false;
        valid = null;
    }


    /**
     * Creates a StringValue without an initial wrapped value.
     *
     * @param attributeType the schema type associated with this StringValue
     */
    public StringValue( MutableAttributeTypeImpl attributeType )
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04442_NULL_AT_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }

        if ( attributeType.getSyntax() == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_04445 ) );
        }

        if ( ! attributeType.getSyntax().isHumanReadable() )
        {
            LOG.warn( "Treating a value of a binary attribute {} as a String: "
                + "\nthis could cause data corruption!", attributeType.getName() );
        }

        this.attributeType = attributeType;
    }


    /**
     * Creates a StringValue with an initial wrapped String value.
     *
     * @param value the value to wrap which can be null
     */
    public StringValue( String value )
    {
        this.wrappedValue = value;
        normalized = false;
        valid = null;
    }


    /**
     * Creates a StringValue with an initial wrapped String value.
     *
     * @param attributeType the schema type associated with this StringValue
     * @param value the value to wrap which can be null
     */
    public StringValue( MutableAttributeTypeImpl attributeType, String value )
    {
        this( attributeType );
        this.wrappedValue = value;
    }


    // -----------------------------------------------------------------------
    // Value<String> Methods
    // -----------------------------------------------------------------------
    /**
     * Get a copy of the stored value.
     *
     * @return A copy of the stored value.
     */
    public String get()
    {
        // The String is immutable, we can safely return the internal
        // object without copying it.
        return wrappedValue;
    }
    
    
    /**
     * Gets the normalized (canonical) representation for the wrapped string.
     * If the wrapped String is null, null is returned, otherwise the normalized
     * form is returned.  If 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 String getNormalizedValue()
    {
        if ( isNull() )
        {
            normalized = true;
            return null;
        }

        if ( !normalized )
        {
            try
            {
                normalize();
            }
            catch ( LdapException ne )
            {
                String message = "Cannot normalize the value :" + ne.getLocalizedMessage();
                LOG.info( message );
                normalized = false;
            }
        }
        
        if ( normalizedValue == null )
        {
            return wrappedValue;
        }

        return normalizedValue;
    }
    
    
    /**
     * Compute the normalized (canonical) representation for the wrapped string.
     * If the wrapped String is null, the normalized form will be null too.  
     *
     * @throws LdapException if the value cannot be properly normalized
     */
    public void normalize() throws LdapException
    {
        // If the value is already normalized, get out.
        if ( normalized )
        {
            return;
        }
        
        if ( attributeType != null )
        {
            Normalizer normalizer = getNormalizer();
    
            if ( normalizer == null )
            {
                normalizedValue = wrappedValue;
            }
            else
            {
                normalizedValue = ( String ) normalizer.normalize( wrappedValue );
            }
    
            normalized = true;
        }
    }

    
    /**
     * Normalize the value. For a client String value, applies the given normalizer.
     * 
     * It supposes that the client has access to the schema in order to select the
     * appropriate normalizer.
     * 
     * @param normalizer The normalizer to apply to the value
     * @exception LdapException If the value cannot be normalized
     */
    public final void normalize( Normalizer normalizer ) throws LdapException
    {
        if ( normalizer != null )
        {
            normalizedValue = (String)normalizer.normalize( wrappedValue );
            normalized = true;
        }
    }

    
    // -----------------------------------------------------------------------
    // Comparable<String> Methods
    // -----------------------------------------------------------------------
    /**
     * @see ServerValue#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<String> value )
    {
        if ( isNull() )
        {
            if ( ( value == null ) || value.isNull() )
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else if ( ( value == null ) || value.isNull() )
        {
            return 1;
        }

        if ( !( value instanceof StringValue ) )
        {
            String message = I18n.err( I18n.ERR_04128, toString(), value.getClass() );
            LOG.error( message );
            throw new NotImplementedException( message );
        }
        
        StringValue stringValue = ( StringValue ) value;
        
        if ( attributeType != null )
        {
            if ( stringValue.getAttributeType() == null )
            {
                return getNormalizedValue().compareTo( stringValue.getNormalizedValue() );
            }
            else
            {
                if ( !attributeType.equals( stringValue.getAttributeType() ) )
                {
                    String message = I18n.err( I18n.ERR_04128, toString(), value.getClass() );
                    LOG.error( message );
                    throw new NotImplementedException( message );
                }
            }
        }
        else 
        {
            return getNormalizedValue().compareTo( stringValue.getNormalizedValue() );
        }
            
        try
        {
            return getLdapComparator().compare( getNormalizedValue(), stringValue.getNormalizedValue() );
        }
        catch ( LdapException e )
        {
            String msg = I18n.err( I18n.ERR_04443, this, value );
            LOG.error( msg, e );
            throw new IllegalStateException( msg, e );
        }
    }


    // -----------------------------------------------------------------------
    // Cloneable methods
    // -----------------------------------------------------------------------
    /**
     * Get a clone of the Client Value
     * 
     * @return a copy of the current value
     */
    public StringValue clone()
    {
        return (StringValue)super.clone();
    }


    // -----------------------------------------------------------------------
    // Object Methods
    // -----------------------------------------------------------------------
    /**
     * @see Object#hashCode()
     * @return the instance's hashcode 
     */
    public int hashCode()
    {
        if ( h == 0 )
        {
            // return zero if the value is null so only one null value can be
            // stored in an attribute - the binary version does the same 
            if ( isNull() )
            {
                return 0;
            }
    
            // If the normalized value is null, will default to wrapped
            // which cannot be null at this point.
            // If the normalized value is null, will default to wrapped
            // which cannot be null at this point.
            String normalized = getNormalizedValue();
            
            if ( normalized != null )
            {
                h = normalized.hashCode();
            }
            else
            {
                h = 17;
            }
        }
        
        return h;
    }


    /**
     * Two StringValue are equals if their normalized values are equal
     * 
     * @see Object#equals(Object)
     */
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }

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

        StringValue other = ( StringValue ) obj;
        
        if ( this.isNull() )
        {
            return other.isNull();
        }
       
        // If we have an attributeType, it must be equal
        // We should also use the comparator if we have an AT
        if ( attributeType != null )
        {
            if ( other.attributeType != null )
            {
                if ( !attributeType.equals( other.attributeType ) )
                {
                    return false;
                }
            }
            else
            {
                return this.getNormalizedValue().equals( other.getNormalizedValue() );
            }
        }
        else if ( other.attributeType != null )
        {
            return this.getNormalizedValue().equals( other.getNormalizedValue() );
        }

        // Shortcut : compare the values without normalization
        // If they are equal, we may avoid a normalization.
        // Note : if two values are equal, then their normalized
        // value are equal too if their attributeType are equal. 
        if ( getReference().equals( other.getReference() ) )
        {
            return true;
        }

        if ( attributeType != null )
        {
            try
            {
                AbstractLdapComparator<String> comparator = getLdapComparator();

                // Compare normalized values
                if ( comparator == null )
                {
                    return getNormalizedValue().equals( other.getNormalizedValue() );
                }
                else
                {
                    if ( isNormalized() )
                    {
                        return comparator.compare( getNormalizedValue(), other.getNormalizedValue() ) == 0;
                    }
                    else
                    {
                        Normalizer normalizer = attributeType.getEquality().getNormalizer();
                        return comparator.compare( normalizer.normalize( get() ), normalizer.normalize( other.get() ) ) == 0;
                    }
                }
            }
            catch ( LdapException ne )
            {
                return false;
            }
        }
        else
        {
            return this.getNormalizedValue().equals( other.getNormalizedValue() );
        }
    }
    
    
    /**
     * Tells if the current value is Binary or String
     * 
     * @return <code>true</code> if the value is Binary, <code>false</code> otherwise
     */
    public boolean isBinary()
    {
        return false;
    }

    
    /**
     * @return The length of the interned value
     */
    public int length()
    {
        return wrappedValue != null ? wrappedValue.length() : 0;
    }
    
    
    /**
     * Get the wrapped value as a byte[].
     * @return the wrapped value as a byte[]
     */
    public byte[] getBytes()
    {
        return Strings.getBytesUtf8(wrappedValue);
    }
    
    
    /**
     * Get the wrapped value as a String.
     *
     * @return the wrapped value as a String
     */
    public String getString()
    {
        return wrappedValue != null ? wrappedValue : "";
    }
    
    
    /**
     * {@inheritDoc}
     */
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // Read the wrapped value, if it's not null
        if ( in.readBoolean() )
        {
            wrappedValue = Unicode.readUTF(in);
        }
        
        // Read the isNormalized flag
        normalized = in.readBoolean();
        
        if ( ( normalized ) && ( in.readBoolean() ) )
        {
            // Read the normalized value, if not null
            normalizedValue = Unicode.readUTF(in);
        }
        
        h = 0;
    }

    
    /**
     * {@inheritDoc}
     */
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        // Write the wrapped value, if it's not null
        if ( wrappedValue != null )
        {
            out.writeBoolean( true );
            Unicode.writeUTF(out, wrappedValue);
        }
        else
        {
            out.writeBoolean( false );
        }
        
        // Write the isNormalized flag
        if ( normalized )
        {
            out.writeBoolean( true );
            
            // Write the normalized value, if not null
            if ( normalizedValue != null )
            {
                out.writeBoolean( true );
                Unicode.writeUTF(out, normalizedValue);
            }
            else
            {
                out.writeBoolean( false );
            }
        }
        else
        {
            out.writeBoolean( false );
        }
        
        // and flush the data
        out.flush();
    }

    
    /**
     * {@inheritDoc}
     */
    public static StringValue deserialize( SchemaManager schemaManager, ObjectInput in ) throws IOException
    {
        return (StringValue)AbstractValue.deserialize( schemaManager, in );
    }

    
    /**
     * @see Object#toString()
     */
    public String toString()
    {
        return wrappedValue == null ? "null": wrappedValue;
    }
}
