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


import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.exception.LdapNoSuchAttributeException;
import org.apache.directory.shared.ldap.model.schema.AttributeType;
import org.apache.directory.shared.ldap.model.schema.MatchingRule;
import org.apache.directory.shared.ldap.model.schema.SchemaObjectType;
import org.apache.directory.shared.ldap.model.schema.normalizers.NoOpNormalizer;
import org.apache.directory.shared.ldap.model.schema.normalizers.OidNormalizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An AttributeType registry service default implementation.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DefaultAttributeTypeRegistry extends DefaultSchemaObjectRegistry<AttributeType> implements
    AttributeTypeRegistry
{
    /** static class logger */
    private static final Logger LOG = LoggerFactory.getLogger( DefaultAttributeTypeRegistry.class );

    /** cached Oid/normalizer mapping */
    private Map<String, OidNormalizer> oidNormalizerMap;

    /** maps OIDs to a Set of descendants for that OID */
    private Map<String, Set<AttributeType>> oidToDescendantSet;


    /**
     * Creates a new default AttributeTypeRegistry instance.
     */
    public DefaultAttributeTypeRegistry()
    {
        super( SchemaObjectType.ATTRIBUTE_TYPE, new OidRegistry<AttributeType>() );
        oidNormalizerMap = new HashMap<String, OidNormalizer>();
        oidToDescendantSet = new HashMap<String, Set<AttributeType>>();
    }


    /**
     * {@inheritDoc}
     */
    public Map<String, OidNormalizer> getNormalizerMapping()
    {
        return Collections.unmodifiableMap( oidNormalizerMap );
    }


    /**
     * {@inheritDoc}
     */
    public boolean hasDescendants( String ancestorId ) throws LdapException
    {
        try
        {
            String oid = getOidByName( ancestorId );
            Set<AttributeType> descendants = oidToDescendantSet.get( oid );
            return ( descendants != null ) && !descendants.isEmpty();
        }
        catch ( LdapException ne )
        {
            throw new LdapNoSuchAttributeException( ne.getMessage() );
        }
    }


    /**
     * {@inheritDoc}
     */
    public boolean hasDescendants( AttributeType ancestor ) throws LdapException
    {
        String oid = ancestor.getOid();
        Set<AttributeType> descendants = oidToDescendantSet.get( oid );
        return ( descendants != null ) && !descendants.isEmpty();
    }


    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public Iterator<AttributeType> descendants( String ancestorId ) throws LdapException
    {
        try
        {
            String oid = getOidByName( ancestorId );
            Set<AttributeType> descendants = oidToDescendantSet.get( oid );

            if ( descendants == null )
            {
                return Collections.EMPTY_SET.iterator();
            }

            return descendants.iterator();
        }
        catch ( LdapException ne )
        {
            throw new LdapNoSuchAttributeException( ne.getMessage() );
        }
    }


    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public Iterator<AttributeType> descendants( AttributeType ancestor ) throws LdapException
    {
        String oid = ancestor.getOid();
        Set<AttributeType> descendants = oidToDescendantSet.get( oid );

        if ( descendants == null )
        {
            return Collections.EMPTY_SET.iterator();
        }

        return descendants.iterator();
    }


    /**
     * {@inheritDoc}
     */
    public void registerDescendants( AttributeType attributeType, AttributeType ancestor ) throws LdapException
    {
        // add this attribute to descendant list of other attributes in superior chain
        if ( ancestor == null )
        {
            return;
        }

        // Get the ancestor's descendant, if any
        Set<AttributeType> descendants = oidToDescendantSet.get( ancestor.getOid() );

        // Initialize the descendant Set to store the descendants for the attributeType
        if ( descendants == null )
        {
            descendants = new HashSet<AttributeType>( 1 );
            oidToDescendantSet.put( ancestor.getOid(), descendants );
        }

        // Add the current type as a descendant
        descendants.add( attributeType );

        /*
        try
        {
            // And recurse until we reach the top of the hierarchy
            registerDescendants( attributeType, ancestor.getSuperior() );
        }
        catch ( LdapException ne )
        {
            throw new NoSuchAttributeException( ne.getMessage() );
        }
        */
    }


    /**
     * {@inheritDoc}
     */
    public void unregisterDescendants( AttributeType attributeType, AttributeType ancestor ) throws LdapException
    {
        // add this attribute to descendant list of other attributes in superior chain
        if ( ancestor == null )
        {
            return;
        }

        // Get the ancestor's descendant, if any
        Set<AttributeType> descendants = oidToDescendantSet.get( ancestor.getOid() );

        if ( descendants != null )
        {
            descendants.remove( attributeType );

            if ( descendants.size() == 0 )
            {
                oidToDescendantSet.remove( ancestor.getOid() );
            }
        }

        /*
        try
        {
            // And recurse until we reach the top of the hierarchy
            unregisterDescendants( attributeType, ancestor.getSuperior() );
        }
        catch ( LdapException ne )
        {
            throw new NoSuchAttributeException( ne.getMessage() );
        }
        */
    }


    /**
     * {@inheritDoc}
     */
    public AttributeType unregister( String numericOid ) throws LdapException
    {
        try
        {
            AttributeType removed = super.unregister( numericOid );

            removeMappingFor( removed );

            // Deleting an AT which might be used as a superior means we have
            // to recursively update the descendant map. We also have to remove
            // the at.oid -> descendant relation
            oidToDescendantSet.remove( numericOid );

            // Now recurse if needed
            unregisterDescendants( removed, removed.getSuperior() );

            return removed;
        }
        catch ( LdapException ne )
        {
            throw new LdapNoSuchAttributeException( ne.getMessage() );
        }
    }


    /**
     * {@inheritDoc}
     */
    public void addMappingFor( AttributeType attributeType ) throws LdapException
    {
        MatchingRule equality = attributeType.getEquality();
        OidNormalizer oidNormalizer;
        String oid = attributeType.getOid();

        if ( equality == null )
        {
            LOG.debug( "Attribute {} does not have an EQUALITY MatchingRule : using NoopNormalizer", attributeType
                .getName() );
            oidNormalizer = new OidNormalizer( oid, new NoOpNormalizer( attributeType.getOid() ) );
        }
        else
        {
            oidNormalizer = new OidNormalizer( oid, equality.getNormalizer() );
        }

        oidNormalizerMap.put( oid, oidNormalizer );

        // Also inject the attributeType's short names in the map
        for ( String name : attributeType.getNames() )
        {
            oidNormalizerMap.put( name.toLowerCase(), oidNormalizer );
        }
    }


    /**
     * Remove the AttributeType normalizer from the OidNormalizer map 
     */
    public void removeMappingFor( AttributeType attributeType ) throws LdapException
    {
        if ( attributeType == null )
        {
            return;
        }

        oidNormalizerMap.remove( attributeType.getOid() );

        // We also have to remove all the short names for this attribute
        for ( String name : attributeType.getNames() )
        {
            oidNormalizerMap.remove( name.toLowerCase() );
        }
    }


    /**
     * {@inheritDoc}
     */
    public AttributeType lookup( String oid ) throws LdapException
    {
        try
        {
            return super.lookup( oid );
        }
        catch ( LdapException ne )
        {
            throw new LdapNoSuchAttributeException( ne.getMessage() );
        }
    }


    /**
     * {@inheritDoc}
     */
    public AttributeTypeRegistry copy()
    {
        DefaultAttributeTypeRegistry copy = new DefaultAttributeTypeRegistry();

        // Copy the base data
        copy.copy( this );

        return copy;
    }


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

        // clear the OidNormalizer map
        oidNormalizerMap.clear();

        // and clear the descendant
        for ( String oid : oidToDescendantSet.keySet() )
        {
            Set<AttributeType> descendants = oidToDescendantSet.get( oid );

            if ( descendants != null )
            {
                descendants.clear();
            }
        }

        oidToDescendantSet.clear();
    }
}
