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


import java.util.List;

import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.schema.registries.Registries;
import org.apache.directory.shared.ldap.schema.syntaxCheckers.OctetStringSyntaxChecker;


/**
 * A syntax definition. Each attribute stored in a directory has a defined
 * syntax (i.e. data type) which constrains the structure and format of its
 * values. The description of each syntax specifies how attribute or assertion
 * values conforming to the syntax are normally represented when transferred in
 * LDAP operations. This representation is referred to as the LDAP-specific
 * encoding to distinguish it from other methods of encoding attribute values.
 * <p>
 * According to ldapbis [MODELS]:
 * </p>
 * 
 * <pre>
 *  4.1.5. LDAP Syntaxes
 *  
 *    LDAP Syntaxes of (attribute and assertion) values are described in
 *    terms of ASN.1 [X.680] and, optionally, have an octet string encoding
 *    known as the LDAP-specific encoding.  Commonly, the LDAP-specific
 *    encoding is constrained to string of Universal Character Set (UCS)
 *    [ISO10646] characters in UTF-8 [UTF-8] form.
 * 
 *    Each LDAP syntax is identified by an object identifier (OID).
 * 
 *    LDAP syntax definitions are written according to the ABNF:
 * 
 *      SyntaxDescription = LPAREN WSP
 *          numericoid                ; object identifier
 *          [ SP &quot;DESC&quot; SP qdstring ] ; description
 *          extensions WSP RPAREN     ; extensions
 * 
 *    where:
 *      [numericoid] is object identifier assigned to this LDAP syntax;
 *      DESC [qdstring] is a short descriptive string; and
 *      [extensions] describe extensions.
 * </pre>
 * 
 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html"> RFC2252 Section 4.3.3</a>
 * @see <a href=
 *      "http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-09.txt">
 *      ldapbis [MODELS]</a>
 * @see DescriptionUtils#getDescription(Syntax)
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
// super.hashCode is final
@SuppressWarnings("PMD.OverrideBothEqualsAndHashcode")
public class LdapSyntax extends AbstractSchemaObject
{
    /** The serialVersionUID */
    public static final long serialVersionUID = 1L;

    /** the human readable flag */
    protected boolean isHumanReadable = false;

    /** The associated SyntaxChecker */
    protected SyntaxChecker syntaxChecker;


    /**
     * Creates a Syntax object using a unique OID.
     * 
     * @param oid the OID for this Syntax
     */
    public LdapSyntax( String oid )
    {
        super( SchemaObjectType.LDAP_SYNTAX, oid );
    }


    /**
     * Creates a Syntax object using a unique OID.
     * 
     * @param oid the OID for this Syntax
     */
    public LdapSyntax( String oid, String description )
    {
        super( SchemaObjectType.LDAP_SYNTAX, oid );
        this.description = description;
    }


    /**
     * Creates a Syntax object using a unique OID.
     * 
     * @param oid the OID for this Syntax
     */
    public LdapSyntax( String oid, String description, boolean isHumanReadable )
    {
        super( SchemaObjectType.LDAP_SYNTAX, oid );
        this.description = description;
        this.isHumanReadable = isHumanReadable;
    }


    /**
     * Gets whether or not the Syntax is human readable.
     * 
     * @return true if the syntax can be interpreted by humans, false otherwise
     */
    public boolean isHumanReadable()
    {
        return isHumanReadable;
    }


    /**
     * Sets the human readable flag value.
     * 
     * @param isHumanReadable the human readable flag value to set
     */
    public void setHumanReadable( boolean isHumanReadable )
    {
        if ( locked )
        {
            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
        }
        
        if ( !isReadOnly )
        {
            this.isHumanReadable = isHumanReadable;
        }
    }


    /**
     * Gets the SyntaxChecker used to validate values in accordance with this
     * Syntax.
     * 
     * @return the SyntaxChecker
     */
    public SyntaxChecker getSyntaxChecker()
    {
        return syntaxChecker;
    }


    /**
     * Sets the associated SyntaxChecker
     *
     * @param syntaxChecker The associated SyntaxChecker
     */
    public void setSyntaxChecker( SyntaxChecker syntaxChecker )
    {
        if ( locked )
        {
            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
        }
        
        if ( !isReadOnly )
        {
            this.syntaxChecker = syntaxChecker;
        }
    }


    /**
     * Update the associated SyntaxChecker, even if the SchemaObject is readOnly
     *
     * @param syntaxChecker The associated SyntaxChecker
     */
    public void updateSyntaxChecker( SyntaxChecker syntaxChecker )
    {
        if ( locked )
        {
            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
        }
        
        this.syntaxChecker = syntaxChecker;
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        return objectType + " " + DescriptionUtils.getDescription( this );
    }


    /**
     * Inject the Syntax into the registries, updating the references to
     * other SchemaObject
     *
     * @param registries The Registries
     * @exception If the addition failed
     */
    public void addToRegistries( List<Throwable> errors, Registries registries ) throws LdapException
    {
        if ( registries != null )
        {
            try
            {
                // Gets the associated SyntaxChecker
                syntaxChecker = registries.getSyntaxCheckerRegistry().lookup( oid );
            }
            catch ( LdapException ne )
            {
                // No SyntaxChecker ? Associate the Syntax to a catch all SyntaxChecker
                syntaxChecker = new OctetStringSyntaxChecker( oid );
            }

            // Add the references for S :
            // S -> SC
            if ( syntaxChecker != null )
            {
                registries.addReference( this, syntaxChecker );
            }
        }
    }
    
    
    /**
     * Remove the SDyntax from the registries, updating the references to
     * other SchemaObject.
     * 
     * If one of the referenced SchemaObject does not exist (), 
     * an exception is thrown.
     *
     * @param registries The Registries
     * @exception If the Syntx is not valid 
     */
    @SuppressWarnings("PMD.CollapsibleIfStatements") // Used because of comments
    public void removeFromRegistries( List<Throwable> errors, Registries registries ) throws LdapException
    {
        if ( registries != null )
        {
            /**
             * Remove the Syntax references (using and usedBy) : 
             * S -> SC
             */
            if ( syntaxChecker != null )
            {
                registries.delReference( this, syntaxChecker );
            }
        }
    }


    /**
     * Copy a LdapSyntax
     */
    public LdapSyntax copy()
    {
        LdapSyntax copy = new LdapSyntax( oid );

        // Copy the SchemaObject common data
        copy.copy( this );

        // Copy the HR flag
        copy.isHumanReadable = isHumanReadable;

        // All the references to other Registries object are set to null.
        copy.syntaxChecker = null;

        return copy;
    }


    /**
     * @see Object#equals()
     */
    @Override
    public boolean equals( Object o )
    {
        if ( !super.equals( o ) )
        {
            return false;
        }

        if ( !( o instanceof LdapSyntax ) )
        {
            return false;
        }

        LdapSyntax that = ( LdapSyntax ) o;

        // IsHR
        if ( isHumanReadable != that.isHumanReadable )
        {
            return false;
        }

        // Check the SyntaxChecker (not a equals)
        return syntaxChecker.getOid().equals( that.syntaxChecker.getOid() );
    }


    /**
     * {@inheritDoc}
     */
    public void clear()
    {
        // Clear the common elements
        super.clear();

        // Clear the references
        syntaxChecker = null;
    }
}
