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


import java.util.List;

import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.ObjectClass;
import org.apache.directory.api.ldap.model.schema.SchemaObject;


/**
 * Utilities for dealing with various schema descriptions.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class ParserDescriptionUtils
{
    /**
     * Private constructor.
     */
    private ParserDescriptionUtils()
    {
    }


    /**
     * Checks two schema objectClasses for an exact match.
     *
     * @param oc0 the first objectClass to compare
     * @param oc1 the second objectClass to compare
     * @return true if both objectClasses match exactly, false otherwise
     */
    public static boolean objectClassesMatch( ObjectClass oc0, ObjectClass oc1 )
    {
        // compare all common description parameters
        if ( !descriptionsMatch( oc0, oc1 ) )
        {
            return false;
        }

        // compare the objectClass type (AUXILIARY, STRUCTURAL, ABSTRACT)
        if ( oc0.getType() != oc1.getType() )
        {
            return false;
        }

        // compare the superior objectClasses (sizes must match)
        if ( oc0.getSuperiorOids().size() != oc1.getSuperiorOids().size() )
        {
            return false;
        }

        // compare the superior objectClasses (sizes must match)
        for ( int i = 0; i < oc0.getSuperiorOids().size(); i++ )
        {
            if ( !oc0.getSuperiorOids().get( i ).equals( oc1.getSuperiorOids().get( i ) ) )
            {
                return false;
            }
        }

        // compare the must attributes (sizes must match)
        for ( int i = 0; i < oc0.getMustAttributeTypeOids().size(); i++ )
        {
            if ( !oc0.getMustAttributeTypeOids().get( i ).equals( oc1.getMustAttributeTypeOids().get( i ) ) )
            {
                return false;
            }
        }

        // compare the may attributes (sizes must match)
        for ( int i = 0; i < oc0.getMayAttributeTypeOids().size(); i++ )
        {
            if ( !oc0.getMayAttributeTypeOids().get( i ).equals( oc1.getMayAttributeTypeOids().get( i ) ) )
            {
                return false;
            }
        }

        return true;
    }


    /**
     * Checks two schema attributeTypes for an exact match.
     *
     * @param at0 the first attributeType to compare
     * @param at1 the second attributeType to compare
     * @return true if both attributeTypes match exactly, false otherwise
     */
    public static boolean attributeTypesMatch( AttributeType at0, AttributeType at1 )
    {
        // compare all common description parameters
        if ( !descriptionsMatch( at0, at1 ) )
        {
            return false;
        }

        // check that the same super type is being used for both attributes
        if ( !at0.getSuperiorOid().equals( at1.getSuperiorOid() ) )
        {
            return false;
        }

        // check that the same matchingRule is used by both ATs for EQUALITY
        if ( !at0.getEqualityOid().equals( at1.getEqualityOid() ) )
        {
            return false;
        }

        // check that the same matchingRule is used by both ATs for SUBSTRING
        if ( !at0.getSubstringOid().equals( at1.getSubstringOid() ) )
        {
            return false;
        }

        // check that the same matchingRule is used by both ATs for ORDERING
        if ( !at0.getOrderingOid().equals( at1.getOrderingOid() ) )
        {
            return false;
        }

        // check that the same syntax is used by both ATs
        if ( !at0.getSyntaxOid().equals( at1.getSyntaxOid() ) )
        {
            return false;
        }

        // check that the syntax length constraint is the same for both
        if ( at0.getSyntaxLength() != at1.getSyntaxLength() )
        {
            return false;
        }

        // check that the ATs have the same single valued flag value
        if ( at0.isSingleValued() != at1.isSingleValued() )
        {
            return false;
        }

        // check that the ATs have the same collective flag value
        if ( at0.isCollective() != at1.isCollective() )
        {
            return false;
        }

        // check that the ATs have the same user modifiable flag value
        if ( at0.isUserModifiable() != at1.isUserModifiable() )
        {
            return false;
        }

        // check that the ATs have the same USAGE
        if ( at0.getUsage() != at1.getUsage() )
        {
            return false;
        }

        return true;
    }


    /**
     * Checks to see if two matchingRule match exactly.
     *
     * @param matchingRule0 the first matchingRule to compare
     * @param matchingRule1 the second matchingRule to compare
     * @return true if the matchingRules match exactly, false otherwise
     */
    public static boolean matchingRulesMatch( MatchingRule matchingRule0, MatchingRule matchingRule1 )
    {
        // compare all common description parameters
        if ( !descriptionsMatch( matchingRule0, matchingRule1 ) )
        {
            return false;
        }

        // check that the syntaxes of the matchingRules match
        if ( !matchingRule0.getSyntaxOid().equals( matchingRule1.getSyntaxOid() ) )
        {
            return false;
        }

        return true;
    }


    /**
     * Checks to see if two syntax match exactly.
     *
     * @param ldapSyntax0 the first ldapSyntax to compare
     * @param ldapSyntax1 the second ldapSyntax to compare
     * @return true if the syntaxes match exactly, false otherwise
     */
    public static boolean syntaxesMatch( LdapSyntax ldapSyntax0, LdapSyntax ldapSyntax1 )
    {
        return descriptionsMatch( ldapSyntax0, ldapSyntax1 );
    }


    /**
     * Checks if two base schema descriptions match for the common components 
     * in every schema description.  NOTE: for syntaxes the obsolete flag is 
     * not compared because doing so would raise an exception since syntax 
     * descriptions do not support the OBSOLETE flag.
     * 
     * @param so0 the first schema description to compare 
     * @param so1 the second schema description to compare 
     * @return true if the descriptions match exactly, false otherwise
     */
    public static boolean descriptionsMatch( SchemaObject so0, SchemaObject so1 )
    {
        // check that the OID matches
        if ( !so0.getOid().equals( so1.getOid() ) )
        {
            return false;
        }

        // check that the obsolete flag is equal but not for syntaxes
        if ( ( ( so0 instanceof LdapSyntax ) || ( so1 instanceof LdapSyntax ) ) && so0.isObsolete() != so1.isObsolete() )
        {
            return false;
        }

        // check that the description matches
        if ( !so0.getDescription().equals( so1.getDescription() ) )
        {
            return false;
        }

        // check alias names for exact match
        if ( !aliasNamesMatch( so0, so1 ) )
        {
            return false;
        }

        // check extensions for exact match
        if ( !extensionsMatch( so0, so1 ) )
        {
            return false;
        }

        return true;
    }


    /**
     * Checks to see if the extensions of a schema description match another
     * description.  The order of the extension values must match for a true
     * return.
     *
     * @param lsd0 the first schema description to compare the extensions of
     * @param lsd1 the second schema description to compare the extensions of
     * @return true if the extensions match exactly, false otherwise
     */
    public static boolean extensionsMatch( SchemaObject lsd0, SchemaObject lsd1 )
    {
        // check sizes first
        if ( lsd0.getExtensions().size() != lsd1.getExtensions().size() )
        {
            return false;
        }

        // check contents and order of extension values must match
        for ( String key : lsd0.getExtensions().keySet() )
        {
            List<String> values0 = lsd0.getExtension( key );
            List<String> values1 = lsd1.getExtension( key );

            // if the key is not present in asd1
            if ( values1 == null )
            {
                return false;
            }

            for ( int i = 0; i < values0.size(); i++ )
            {
                if ( !values0.get( i ).equals( values1.get( i ) ) )
                {
                    return false;
                }
            }
        }

        return true;
    }


    /**
     * Checks to see if the alias names of a schema description match another 
     * description.  The order of the alias names do matter.
     *
     * @param so0 the schema description to compare
     * @param so1 the schema description to compare
     * @return true if alias names match exactly, false otherwise
     */
    public static boolean aliasNamesMatch( SchemaObject so0, SchemaObject so1 )
    {
        // check sizes first
        if ( so0.getNames().size() != so1.getNames().size() )
        {
            return false;
        }

        // check contents and order must match too
        for ( int i = 0; i < so0.getNames().size(); i++ )
        {
            if ( !so0.getNames().get( i ).equals( so1.getNames().get( i ) ) )
            {
                return false;
            }
        }

        return true;
    }
}
