/*
 *  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.xdbm.search.impl;


import java.util.ArrayList;
import java.util.List;

import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.xdbm.Store;
import org.apache.directory.server.xdbm.search.Evaluator;
import org.apache.directory.shared.ldap.NotImplementedException;
import org.apache.directory.shared.ldap.filter.AndNode;
import org.apache.directory.shared.ldap.filter.ApproximateNode;
import org.apache.directory.shared.ldap.filter.EqualityNode;
import org.apache.directory.shared.ldap.filter.ExprNode;
import org.apache.directory.shared.ldap.filter.GreaterEqNode;
import org.apache.directory.shared.ldap.filter.LessEqNode;
import org.apache.directory.shared.ldap.filter.NotNode;
import org.apache.directory.shared.ldap.filter.OrNode;
import org.apache.directory.shared.ldap.filter.PresenceNode;
import org.apache.directory.shared.ldap.filter.ScopeNode;
import org.apache.directory.shared.ldap.filter.SearchScope;
import org.apache.directory.shared.ldap.filter.SubstringNode;
import org.apache.directory.shared.ldap.schema.SchemaManager;


/**
 * Top level filter expression evaluator builder implemenation.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class EvaluatorBuilder
{
    private final Store<ServerEntry> db;
    private final SchemaManager schemaManager;


    /**
     * Creates a top level Evaluator where leaves are delegated to a leaf node
     * evaluator which will be created.
     *
     * @param db the database this evaluator operates upon
     * @param registries the schema registries
     * @throws Exception failure to access db or lookup schema in registries
     */
    public EvaluatorBuilder( Store<ServerEntry> db, SchemaManager schemaManager ) throws Exception
    {
        this.db = db;
        this.schemaManager = schemaManager;
    }


    public Evaluator<? extends ExprNode, ServerEntry> build( ExprNode node ) throws Exception
    {
        switch ( node.getAssertionType() )
        {
            /* ---------- LEAF NODE HANDLING ---------- */

            case APPROXIMATE:
                return new ApproximateEvaluator( ( ApproximateNode ) node, db, schemaManager );
                
            case EQUALITY:
                return new EqualityEvaluator( ( EqualityNode ) node, db, schemaManager );
                
            case GREATEREQ:
                return new GreaterEqEvaluator( ( GreaterEqNode ) node, db, schemaManager );
                
            case LESSEQ:
                return new LessEqEvaluator( ( LessEqNode ) node, db, schemaManager );
                
            case PRESENCE:
                return new PresenceEvaluator( ( PresenceNode ) node, db, schemaManager );
                
            case SCOPE:
                if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
                {
                    return new OneLevelScopeEvaluator<ServerEntry>( db, ( ScopeNode ) node );
                }
                else
                {
                    return new SubtreeScopeEvaluator<ServerEntry>( db, ( ScopeNode ) node );
                }
                
            case SUBSTRING:
                return new SubstringEvaluator( ( SubstringNode ) node, db, schemaManager );

            /* ---------- LOGICAL OPERATORS ---------- */

            case AND:
                return buildAndEvaluator( ( AndNode ) node );
                
            case NOT:
                return new NotEvaluator( ( NotNode ) node, build( ( ( NotNode ) node).getFirstChild() ) );
                
            case OR:
                return buildOrEvaluator( ( OrNode ) node );

            /* ----------  NOT IMPLEMENTED  ---------- */

            case ASSERTION:
            case EXTENSIBLE:
                throw new NotImplementedException();

            default:
                throw new IllegalStateException( "Unknown assertion type: " + node.getAssertionType() );
        }
    }


    AndEvaluator buildAndEvaluator( AndNode node ) throws Exception
    {
        List<ExprNode> children = node.getChildren();
        List<Evaluator<? extends ExprNode,ServerEntry>> evaluators =
            new ArrayList<Evaluator<? extends ExprNode,ServerEntry>>( children.size() );
        for ( ExprNode child : children )
        {
            evaluators.add( build( child ) );
        }
        return new AndEvaluator( node, evaluators );
    }


    OrEvaluator buildOrEvaluator( OrNode node ) throws Exception
    {
        List<ExprNode> children = node.getChildren();
        List<Evaluator<? extends ExprNode,ServerEntry>> evaluators =
            new ArrayList<Evaluator<? extends ExprNode,ServerEntry>>( children.size() );
        for ( ExprNode child : children )
        {
            evaluators.add( build( child ) );
        }
        return new OrEvaluator( node, evaluators );
    }
}
