/*
 *  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.server.core.subtree;


import java.util.Iterator;

import javax.naming.Name;
import javax.naming.NamingException;

import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.event.Evaluator;
import org.apache.directory.server.core.event.ExpressionEvaluator;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.server.schema.registries.OidRegistry;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
import org.apache.directory.shared.ldap.util.NamespaceTools;


/**
 * An evaluator used to determine if an entry is included in the collection
 * represented by a subtree specification.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class SubtreeEvaluator
{
    /** A refinement filter evaluator */
    private final Evaluator evaluator;


    /**
     * Creates a subtreeSpecification evaluatior which can be used to determine
     * if an entry is included within the collection of a subtree.
     *
     * @param oidRegistry a registry used to lookup objectClass names for OIDs
     * @param attrRegistry registry to be looked up
     * @throws NamingException 
     */
    public SubtreeEvaluator( OidRegistry oidRegistry, AttributeTypeRegistry attrRegistry )
    {
        evaluator = new ExpressionEvaluator(oidRegistry, attrRegistry );
    }


    /**
     * Determines if an entry is selected by a subtree specification.
     *
     * @param subtree the subtree specification
     * @param apDn the distinguished name of the administrative point containing the subentry
     * @param entryDn the distinguished name of the candidate entry
     * @return true if the entry is selected by the specification, false if it is not
     * @throws javax.naming.NamingException if errors are encountered while evaluating selection
     */
    public boolean evaluate( SubtreeSpecification subtree, Name apDn, Name entryDn, ServerEntry entry )
        throws NamingException
    {
        // TODO: Try to make this cast unnecessary.
        LdapDN entryLdapDn = (LdapDN) entryDn;
        
        /* =====================================================================
         * NOTE: Regarding the overall approach, we try to narrow down the
         * possibilities by slowly pruning relative names off of the entryDn.
         * For example we check first if the entry is a descendant of the AP.
         * If so we use the relative name thereafter to calculate if it is
         * a descendant of the base.  This means shorter names to compare and
         * less work to do while we continue to deduce inclusion by the subtree
         * specification.
         * =====================================================================
         */

        /*
         * First we simply check if the candidate entry is a descendant of the
         * administrative point.  In the process we calculate the relative
         * distinguished name relative to the administrative point.
         */
        Name apRelativeRdn;
        
        if ( !NamespaceTools.isDescendant( apDn, entryDn ) )
        {
            return false;
        }
        else if ( apDn.equals( entryDn ) )
        {
            apRelativeRdn = new LdapDN();
        }
        else
        {
            apRelativeRdn = NamespaceTools.getRelativeName( apDn, entryDn );
        }

        /*
         * We do the same thing with the base as we did with the administrative
         * point: check if the entry is a descendant of the base and find the
         * relative name of the entry with respect to the base rdn.  With the
         * baseRelativeRdn we can later make comparisons with specific exclusions.
         */
        Name baseRelativeRdn;
        
        if ( subtree.getBase() != null && subtree.getBase().size() == 0 )
        {
            baseRelativeRdn = apRelativeRdn;
        }
        else if ( apRelativeRdn.equals( subtree.getBase() ) )
        {
            baseRelativeRdn = new LdapDN();
        }
        else if ( !NamespaceTools.isDescendant( subtree.getBase(), apRelativeRdn ) )
        {
            return false;
        }
        else
        {
            baseRelativeRdn = NamespaceTools.getRelativeName( subtree.getBase(), apRelativeRdn );
        }

        /*
         * Evaluate based on minimum and maximum chop values.  Here we simply
         * need to compare the distances respectively with the size of the
         * baseRelativeRdn.  For the max distance entries with a baseRelativeRdn
         * size greater than the max distance are rejected.  For the min distance
         * entries with a baseRelativeRdn size less than the minimum distance
         * are rejected.
         */
        if ( subtree.getMaxBaseDistance() != SubtreeSpecification.UNBOUNDED_MAX )
        {
            if ( subtree.getMaxBaseDistance() < baseRelativeRdn.size() )
            {
                return false;
            }
        }

        if ( subtree.getMinBaseDistance() > 0 )
        {
            if ( baseRelativeRdn.size() < subtree.getMinBaseDistance() )
            {
                return false;
            }
        }

        /*
         * For specific exclusions we must iterate through the set and check
         * if the baseRelativeRdn is a descendant of the exclusion.  The
         * isDescendant() function will return true if the compared names
         * are equal so for chopAfter exclusions we must check for equality
         * as well and reject if the relative names are equal.
         */
        Iterator list = subtree.getChopBeforeExclusions().iterator();
        
        while ( list.hasNext() )
        {
            Name chopBefore = ( Name ) list.next();
            
            if ( NamespaceTools.isDescendant( chopBefore, baseRelativeRdn ) )
            {
                return false;
            }
        }

        list = subtree.getChopAfterExclusions().iterator();
        
        while ( list.hasNext() )
        {
            Name chopAfter = ( Name ) list.next();
            
            if ( NamespaceTools.isDescendant( chopAfter, baseRelativeRdn ) && !chopAfter.equals( baseRelativeRdn ) )
            {
                return false;
            }
        }

        /*
         * The last remaining step is to check and see if the refinement filter
         * selects the entry candidate based on objectClass attribute values.
         * To do this we invoke the refinement evaluator members evaluate() method.
         */
        if ( subtree.getRefinement() != null )
        {
            return evaluator.evaluate( subtree.getRefinement(), entryLdapDn.toNormName(), entry );
        }

        /*
         * If nothing has rejected the candidate entry and there is no refinement
         * filter then the entry is included in the collection represented by the
         * subtree specification so we return true.
         */
        return true;
    }
}
