/*
 *   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.
 *
 */

/*
 * $Id$
 *
 * -- (c) LDAPd Group                                                    --
 * -- Please refer to the LICENSE.txt file in the root directory of      --
 * -- any LDAPd project for copyright and distribution information.      --
 *
 * Created on Oct 9, 2003
 */
package org.apache.ldap.server.db;


import org.apache.ldap.common.filter.ExprNode;
import org.apache.ldap.common.filter.ScopeNode;
import org.apache.ldap.common.message.DerefAliasesEnum;

import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import java.math.BigInteger;


/**
 * Evaluates ScopeNode assertions on candidates using a database.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class ScopeEvaluator implements Evaluator
{
    /** Database used to evaluate scope with */
    private Database db;


    /**
     * Creates a scope node evaluator for search expressions.
     *
     * @param db the database used to evaluate scope node
     */
    public ScopeEvaluator( Database db )
    {
        this.db = db;
    }


    /**
     * @see org.apache.ldap.server.db.Evaluator#evaluate(ExprNode, org.apache.ldap.server.db.IndexRecord)
     */
    public boolean evaluate( ExprNode node, IndexRecord record )
        throws NamingException
    {
        ScopeNode snode = ( ScopeNode ) node;
        
        switch( snode.getScope() )
        {
        case( SearchControls.OBJECT_SCOPE ):
            String dn = db.getEntryDn( record.getEntryId() );
            return dn.equals( snode.getBaseDn() );
        case( SearchControls.ONELEVEL_SCOPE ):
            return assertOneLevelScope( snode, record.getEntryId() );
        case( SearchControls.SUBTREE_SCOPE ):
            return assertSubtreeScope( snode, record.getEntryId() );
        default:
            throw new NamingException( "Unrecognized search scope!" );
        }
    }
    
    
    /**
     * Asserts whether or not a candidate has one level scope while taking
     * alias dereferencing into account.
     * 
     * @param node the scope node containing the base and alias handling mode
     * @param id the candidate to assert which can be any db entry's id
     * @return true if the candidate is within one level scope whether or not
     * alias dereferencing is enabled.
     * @throws NamingException if the index lookups fail.
     */
    public boolean assertSubtreeScope( final ScopeNode node, 
        final BigInteger id ) throws NamingException
    {
        String dn = db.getEntryDn( id );
        DerefAliasesEnum mode = node.getDerefAliases();
        Object baseId = db.getEntryId( node.getBaseDn() );
        boolean isDescendant = dn.endsWith( node.getBaseDn() );
        
        /*
         * The candidate id could be any entry in the db.  If search 
         * dereferencing is not enabled then we return the results of the 
         * descendant test.
         */
        if ( ! mode.derefInSearching() )
        {
            return isDescendant;
        }

        /*
         * From here down alias dereferencing is enabled.  We determine if the
         * candidate id is an alias, if so we reject it since aliases should
         * not be returned.
         */
        Index idx = db.getAliasIndex();
        if ( null != idx.reverseLookup( id ) )
        {
            return false;
        }
        
        /*
         * The candidate is NOT an alias at this point.  So if it is a 
         * descendant we just return it since it is in normal subtree scope.
         */
        if ( isDescendant )
        {
            return true;
        }
        
        /*
         * At this point the candidate is not a descendant and it is not an 
         * alias.  We need to check if the candidate is in extended subtree 
         * scope by performing a lookup on the subtree alias index.  This index 
         * stores a tuple mapping the baseId to the ids of objects brought 
         * into subtree scope of the base by an alias: 
         * 
         * ( baseId, aliasedObjId )
         * 
         * If the candidate id is an object brought into subtree scope then 
         * the lookup returns true accepting the candidate.  Otherwise the 
         * candidate is rejected with a false return because it is not in scope.
         */
        idx = db.getSubAliasIndex();
        return idx.hasValue( baseId, id );
    }
    
    
    /**
     * Asserts whether or not a candidate has one level scope while taking
     * alias dereferencing into account.
     * 
     * @param node the scope node containing the base and alias handling mode
     * @param id the candidate to assert which can be any db entry's id 
     * @return true if the candidate is within one level scope whether or not
     * alias dereferencing is enabled.
     * @throws NamingException if the index lookups fail.
     */
    public boolean assertOneLevelScope( final ScopeNode node, 
        final BigInteger id ) throws NamingException
    {
        DerefAliasesEnum mode = node.getDerefAliases();
        Object baseId = db.getEntryId( node.getBaseDn() );
        Index idx = db.getHierarchyIndex();
        boolean isChild = idx.hasValue( baseId, id );

        /*
         * The candidate id could be any entry in the db.  If search 
         * dereferencing is not enabled then we return the results of the child 
         * test. 
         */
        if ( ! mode.derefInSearching() )
        {
            return isChild;
        }

        /*
         * From here down alias dereferencing is enabled.  We determine if the
         * candidate id is an alias, if so we reject it since aliases should
         * not be returned.
         */
        idx = db.getAliasIndex();
        if ( null != idx.reverseLookup( id ) )
        {
            return false;
        }
        
        /*
         * The candidate is NOT an alias at this point.  So if it is a child we
         * just return it since it is in normal one level scope.
         */
        if ( isChild )
        {
            return true;
        }
        
        /*
         * At this point the candidate is not a child and it is not an alias.
         * We need to check if the candidate is in extended one level scope by 
         * performing a lookup on the one level alias index.  This index stores
         * a tuple mapping the baseId to the id of objects brought into the 
         * one level scope of the base by an alias: ( baseId, aliasedObjId )
         * If the candidate id is an object brought into one level scope then 
         * the lookup returns true accepting the candidate.  Otherwise the 
         * candidate is rejected with a false return because it is not in scope.
         */
        idx = db.getOneAliasIndex();
        return idx.hasValue( baseId, id );
    }
}
