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


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

import org.apache.commons.collections.CollectionUtils;


/**
 * Node representing branches within the expression tree corresponding to
 * logical operators within the filter expression.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class BranchNode extends AbstractExprNode
{
    /** child node list for this branch node */
    protected List<ExprNode> children = null;


    /**
     * Creates a BranchNode using a logical operator and a list of children.
     * @param assertionType the node's type
     * @param childList the child nodes under this branch node.
     */
    protected BranchNode( AssertionType assertionType, List<ExprNode> childList )
    {
        super( assertionType );

        if ( null == childList )
        {
            this.children = new ArrayList<ExprNode>( 2 );
        }
        else
        {
            this.children = childList;
        }
        
        isSchemaAware = true;
    }


    /**
     * Creates a BranchNode using a logical operator and a list of children.
     * 
     * @param assertionType the node's type
     * @param childList the child nodes under this branch node.
     */
    protected BranchNode( AssertionType assertionType, ExprNode... childList )
    {
        super( assertionType );

        if ( null == children )
        {
            this.children = new ArrayList<ExprNode>( childList.length );
        }
        
        CollectionUtils.addAll( children, childList );
    }


    /**
     * Creates a BranchNode using a logical operator.
     * 
     * @param assertionType the node's type
     */
    protected BranchNode( AssertionType assertionType )
    {
        super( assertionType );
        
        this.children = new ArrayList<ExprNode>( 2 );
        isSchemaAware = true;
    }

    
    /**
     * @see org.apache.directory.shared.ldap.filter.ExprNode#isLeaf()
     * @return false all the time.
     */
    public final boolean isLeaf()
    {
        return false;
    }

    /**
     * Makes a full clone in new memory space of the current node and children
     * 
     * @return the clone
     */
    @Override public ExprNode clone()
    {
        ExprNode clone = (ExprNode)super.clone();
        
        // Clone the children
        if ( children != null )
        {
            ((BranchNode)clone).children = new ArrayList<ExprNode>();
            
            for ( ExprNode child : children )
            {
                ((BranchNode)clone).children.add( (ExprNode)child.clone() );
            }
        }
        
        return clone;
    }


    /**
     * Adds a child node to this branch node node
     * 
     * @param node the child expression to add to this branch node
     */
    public void addNode( ExprNode node )
    {
        children.add( node );
    }


    /**
     * Adds a child node to this branch node at the head rather than the tail. 
     * 
     * @param node the child expression to add to this branch node
     */
    public void addNodeToHead( ExprNode node )
    {
        children.add( 0, node );
    }

    
    /**
     * Gets the children below this BranchNode. We purposefully do not clone the
     * array list so that backends can sort the order of children using their
     * own search optimization algorithms. We want backends and other parts of
     * the system to be able to induce side effects on the tree structure.
     * 
     * @return the list of child nodes under this branch node.
     */
    public List<ExprNode> getChildren()
    {
        return children;
    }


    /**
     * Sets the list of children under this node.
     * 
     * @param list the list of children to set.
     */
    public void setChildren( List<ExprNode> list )
    {
        children = list;
    }
    
    /**
     * Convenience method that gets the first child in the children array. Its
     * very useful for NOT nodes since they only have one child by avoiding code
     * that looks like: <code> ( ExprNode ) m_children.get( 0 ) </code>
     * 
     * @return the first child
     */
    public ExprNode getFirstChild()
    {
        if ( children.size() > 0 )
        {
            return children.get( 0 );
        }

        return null;
    }


    /**
     * @see org.apache.directory.shared.ldap.filter.ExprNode#accept(
     *      org.apache.directory.shared.ldap.filter.FilterVisitor)
     *      
     * @return The modified element
     */
    public final Object accept( FilterVisitor visitor )
    {
        if ( visitor.isPrefix() )
        {
            List<ExprNode> childrenList = visitor.getOrder( this, this.children );
            ExprNode result = null;

            if ( visitor.canVisit( this ) )
            {
                result = (ExprNode)visitor.visit( this );
            }

            for ( ExprNode node:childrenList )
            {
                node.accept( visitor );
            }

            return result;
        }
        else
        {
            if ( visitor.canVisit( this ) )
            {
                return visitor.visit( this );
            }
            else
            {
                return null;
            }
        }
    }
    
    
    /**
     * (non-Javadoc)
     * 
     * @see Object#hashCode()
     * @return the instance's hash code 
     */
    public int hashCode()
    {
        int h = 37;
        
        h = h*17 + super.hashCode();
        
        if ( children != null )
        {
            for ( ExprNode child:children )
            {
                h = h*17 + child.hashCode();
            }
        }
        
        return h;
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals( Object other )
    {
        if ( this == other )
        {
            return true;
        }

        if ( !( other instanceof BranchNode ) )
        {
            return false;
        }
        
        if ( other.getClass() != this.getClass() )
        {
            return false;
        }

        BranchNode otherExprNode = ( BranchNode ) other;

        List<ExprNode> otherChildren = otherExprNode.getChildren();

        if ( otherChildren == children )
        {
            return true;
        }

        if ( children.size() != otherChildren.size() )
        {
            return false;
        }
        
        for ( int i = 0; i < children.size(); i++ )
        {
            ExprNode child = children.get( i );
            ExprNode otherChild = children.get( i );
            
            if ( !child.equals( otherChild ) )
            {
                return false;
            }
        }
        
        return true;
    }
}
