/*
 *   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.
 *
 */
package org.apache.ldap.server.partition.impl.btree;


import java.math.BigInteger;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;

import org.apache.ldap.common.exception.LdapContextNotEmptyException;
import org.apache.ldap.common.exception.LdapNameNotFoundException;
import org.apache.ldap.common.filter.ExprNode;
import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.ldap.common.schema.AttributeType;
import org.apache.ldap.common.util.ArrayUtils;
import org.apache.ldap.server.configuration.ContextPartitionConfiguration;
import org.apache.ldap.server.enumeration.SearchResultEnumeration;
import org.apache.ldap.server.jndi.ContextFactoryConfiguration;
import org.apache.ldap.server.partition.ContextPartition;
import org.apache.ldap.server.partition.Oid;
import org.apache.ldap.server.partition.impl.btree.gui.PartitionViewer;
import org.apache.ldap.server.schema.AttributeTypeRegistry;
import org.apache.ldap.server.schema.OidRegistry;


/**
 * An abstract {@link ContextPartition} that uses general BTree operations.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public abstract class BTreeContextPartition implements ContextPartition
{
    /** ===================================================================

     The following OID branch is reserved for the directory TLP once it
     graduates the incubator:

       1.2.6.1.4.1.18060.1.1

     The following branch is reserved for the apache directory server:

       1.2.6.1.4.1.18060.1.1.1

      The following branch is reserved for use by apache directory server Syntaxes:

        1.2.6.1.4.1.18060.1.1.1.1

      The following branch is reserved for use by apache directory server MatchingRules:

        1.2.6.1.4.1.18060.1.1.1.2

      The following branch is reserved for use by apache directory server AttributeTypes:

        1.2.6.1.4.1.18060.1.1.1.3

          * 1.2.6.1.4.1.18060.1.1.1.3.1 - apacheNdn
          * 1.2.6.1.4.1.18060.1.1.1.3.2 - apacheUpdn
          * 1.2.6.1.4.1.18060.1.1.1.3.3 - apacheExistance
          * 1.2.6.1.4.1.18060.1.1.1.3.4 - apacheHierarchy
          * 1.2.6.1.4.1.18060.1.1.1.3.5 - apacheOneAlias
          * 1.2.6.1.4.1.18060.1.1.1.3.6 - apacheSubAlias
          * 1.2.6.1.4.1.18060.1.1.1.3.7 - apacheAlias

      The following branch is reserved for use by apache directory server ObjectClasses:

        1.2.6.1.4.1.18060.1.1.1.4

    ==================================================================== */


    /**
     * the search engine used to search the database
     */
    private SearchEngine searchEngine = null;


    // ------------------------------------------------------------------------
    // C O N S T R U C T O R S
    // ------------------------------------------------------------------------

    /**
     * Creates a B-tree based context partition.
     */
    protected BTreeContextPartition()
    {
    }
    

    public void init( ContextFactoryConfiguration factoryCfg, ContextPartitionConfiguration cfg ) throws NamingException
    {
        AttributeTypeRegistry attributeTypeRegistry = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry();
        OidRegistry oidRegistry = factoryCfg.getGlobalRegistries().getOidRegistry();
        ExpressionEvaluator evaluator = new ExpressionEvaluator( this, oidRegistry, attributeTypeRegistry );
        ExpressionEnumerator enumerator = new ExpressionEnumerator( this, attributeTypeRegistry, evaluator );
        this.searchEngine = new DefaultSearchEngine( this, evaluator, enumerator );

        HashSet sysOidSet = new HashSet();
        sysOidSet.add( Oid.EXISTANCE );
        sysOidSet.add( Oid.HIERARCHY );
        sysOidSet.add( Oid.UPDN );
        sysOidSet.add( Oid.NDN );
        sysOidSet.add( Oid.ONEALIAS );
        sysOidSet.add( Oid.SUBALIAS );
        sysOidSet.add( Oid.ALIAS );

        Iterator i = cfg.getIndexedAttributes().iterator();
        while( i.hasNext() )
        {
            String name = ( String ) i.next();
            String oid = oidRegistry.getOid( name );
            AttributeType type = attributeTypeRegistry.lookup( oid );
            
            // check if attribute is a system attribute
            if ( sysOidSet.contains( oid ) )
            {
                if ( oid.equals( Oid.EXISTANCE ) )
                {
                    setExistanceIndexOn( type );
                }
                else if ( oid.equals( Oid.HIERARCHY ) )
                {
                    setHierarchyIndexOn( type );
                }
                else if ( oid.equals( Oid.UPDN ) )
                {
                    setUpdnIndexOn( type );
                }
                else if ( oid.equals( Oid.NDN ) )
                {
                    setNdnIndexOn( type );
                }
                else if ( oid.equals( Oid.ONEALIAS ) )
                {
                    setOneAliasIndexOn( type );
                }
                else if ( oid.equals( Oid.SUBALIAS ) )
                {
                    setSubAliasIndexOn( type );
                }
                else if ( oid.equals( Oid.ALIAS ) )
                {
                    setAliasIndexOn( type );
                }
                else
                {
                    throw new NamingException( "Unidentified system index "
                        + oid );
                }
            }
            else
            {
                addIndexOn( type );
            }
        }
        
        add( cfg.getSuffix(),
                cfg.getNormalizedSuffix( factoryCfg.getGlobalRegistries().getMatchingRuleRegistry() ),
                cfg.getContextEntry() );
    }

    
    // ------------------------------------------------------------------------
    // Public Accessors - not declared in any interfaces just for this class
    // ------------------------------------------------------------------------


    /**
     * Gets the DefaultSearchEngine used by this ContextPartition to search the
     * Database. 
     *
     * @return the search engine
     */
    public SearchEngine getSearchEngine()
    {
        return searchEngine;
    }


    // ------------------------------------------------------------------------
    // ContextPartition Interface Method Implementations
    // ------------------------------------------------------------------------


    public void delete( Name dn ) throws NamingException
    {
        BigInteger id = getEntryId( dn.toString() );

        // don't continue if id is null
        if ( id == null )
        {
            throw new LdapNameNotFoundException( "Could not find entry at '"
                    + dn + "' to delete it!");
        }

        if ( getChildCount( id ) > 0 )
        {
            LdapContextNotEmptyException cnee = new LdapContextNotEmptyException(
                "[66] Cannot delete entry " + dn + " it has children!" );
            cnee.setRemainingName( dn );
            throw cnee;
        }
        
        delete( id );
    }
    
    public abstract void add( String updn, Name dn, Attributes entry ) throws NamingException;
    public abstract void modify( Name dn, int modOp, Attributes mods ) throws NamingException;
    public abstract void modify( Name dn, ModificationItem[] mods ) throws NamingException;


    public NamingEnumeration list( Name base ) throws NamingException
    {
        SearchResultEnumeration list;
        list = new BTreeSearchResultEnumeration( ArrayUtils.EMPTY_STRING_ARRAY,
                list( getEntryId( base.toString() ) ), this );
        return list;
    }
    
    
    public NamingEnumeration search( Name base, Map env, ExprNode filter,
                                     SearchControls searchCtls )
        throws NamingException
    {
        String [] attrIds = searchCtls.getReturningAttributes();
        NamingEnumeration underlying = null;
        
        underlying = searchEngine.search( base, env, filter, searchCtls );
        
        return new BTreeSearchResultEnumeration( attrIds, underlying, this );
    }


    public Attributes lookup( Name dn ) throws NamingException
    {
        return lookup( getEntryId( dn.toString() ) );
    }


    public Attributes lookup( Name dn, String [] attrIds ) throws NamingException
    {
        if ( attrIds == null || attrIds.length == 0 )
        {
            return lookup( dn );
        }

        Attributes entry = lookup( dn );
        Attributes retval = new LockableAttributesImpl();

        for ( int ii = 0; ii < attrIds.length; ii++ )
        {
            Attribute attr = entry.get( attrIds[0] );

            if ( attr != null )
            {
                retval.put( attr );
            }
        }

        return retval;
    }


    public boolean hasEntry( Name dn ) throws NamingException
    {
        return null != getEntryId( dn.toString() );
    }


    public abstract void modifyRn( Name dn, String newRdn, boolean deleteOldRdn ) throws NamingException;
    public abstract void move( Name oldChildDn, Name newParentDn ) throws NamingException;
    public abstract void move( Name oldChildDn, Name newParentDn, String newRdn,
        boolean deleteOldRdn ) throws NamingException;


    public abstract void sync() throws NamingException;
    public abstract void destroy();
    public abstract boolean isInitialized();

    public boolean isSuffix( Name dn ) throws NamingException
    {
        return getSuffix( true ).equals( dn ) ;
    }


    public void inspect() throws Exception
    {
        PartitionViewer viewer = new PartitionViewer( this, searchEngine );
        viewer.execute();
    }
    
    ////////////////////
    // public abstract methods
    
    // ------------------------------------------------------------------------
    // Index Operations 
    // ------------------------------------------------------------------------


    public abstract void addIndexOn( AttributeType attribute ) throws NamingException;
    public abstract boolean hasUserIndexOn( String attribute );
    public abstract boolean hasSystemIndexOn( String attribute );
    public abstract Index getExistanceIndex();

    /**
     * Gets the Index mapping the BigInteger primary keys of parents to the 
     * BigInteger primary keys of their children.
     *
     * @return the hierarchy Index
     */
    public abstract Index getHierarchyIndex();
    
    /**
     * Gets the Index mapping user provided distinguished names of entries as 
     * Strings to the BigInteger primary keys of entries.
     *
     * @return the user provided distinguished name Index
     */
    public abstract Index getUpdnIndex();

    /**
     * Gets the Index mapping the normalized distinguished names of entries as
     * Strings to the BigInteger primary keys of entries.  
     *
     * @return the normalized distinguished name Index
     */
    public abstract Index getNdnIndex();

    /**
     * Gets the alias index mapping parent entries with scope expanding aliases 
     * children one level below them; this system index is used to dereference
     * aliases on one/single level scoped searches.
     * 
     * @return the one alias index
     */
    public abstract Index getOneAliasIndex();

    /**
     * Gets the alias index mapping relative entries with scope expanding 
     * alias descendents; this system index is used to dereference aliases on 
     * subtree scoped searches.
     * 
     * @return the sub alias index
     */
    public abstract Index getSubAliasIndex();

    /**
     * Gets the system index defined on the ALIAS_ATTRIBUTE which for LDAP would
     * be the aliasedObjectName and for X.500 would be aliasedEntryName.
     * 
     * @return the index on the ALIAS_ATTRIBUTE
     */
    public abstract Index getAliasIndex();

    /**
     * Sets the system index defined on the ALIAS_ATTRIBUTE which for LDAP would
     * be the aliasedObjectName and for X.500 would be aliasedEntryName.
     * 
     * @param attrType the index on the ALIAS_ATTRIBUTE
     */
    public abstract void setAliasIndexOn( AttributeType attrType ) throws NamingException;

    /**
     * Sets the attribute existance Index.
     *
     * @param attrType the attribute existance Index
     */    
    public abstract void setExistanceIndexOn( AttributeType attrType ) throws NamingException;

    /**
     * Sets the hierarchy Index.
     *
     * @param attrType the hierarchy Index
     */    
    public abstract void setHierarchyIndexOn( AttributeType attrType ) throws NamingException;

    /**
     * Sets the user provided distinguished name Index.
     *
     * @param attrType the updn Index
     */    
    public abstract void setUpdnIndexOn( AttributeType attrType ) throws NamingException;

    /**
     * Sets the normalized distinguished name Index.
     *
     * @param attrType the ndn Index
     */    
    public abstract void setNdnIndexOn( AttributeType attrType ) throws NamingException;
    
    /**
     * Sets the alias index mapping parent entries with scope expanding aliases 
     * children one level below them; this system index is used to dereference
     * aliases on one/single level scoped searches.
     * 
     * @param attrType a one level alias index
     */
    public abstract void setOneAliasIndexOn( AttributeType attrType ) throws NamingException;
    
    /**
     * Sets the alias index mapping relative entries with scope expanding 
     * alias descendents; this system index is used to dereference aliases on 
     * subtree scoped searches.
     * 
     * @param attrType a subtree alias index
     */
    public abstract void setSubAliasIndexOn( AttributeType attrType ) throws NamingException;
    public abstract Index getUserIndex( String attribute ) throws IndexNotFoundException;
    public abstract Index getSystemIndex( String attribute ) throws IndexNotFoundException;
    public abstract BigInteger getEntryId( String dn ) throws NamingException;
    public abstract String getEntryDn( BigInteger id ) throws NamingException;
    public abstract BigInteger getParentId( String dn ) throws NamingException;
    public abstract BigInteger getParentId( BigInteger childId ) throws NamingException;

    /**
     * Gets the user provided distinguished name.
     *
     * @param id the entry id
     * @return the user provided distinguished name
     * @throws NamingException if the updn index cannot be accessed
     */
    public abstract String getEntryUpdn( BigInteger id ) throws NamingException;

    /**
     * Gets the user provided distinguished name.
     *
     * @param dn the normalized distinguished name
     * @return the user provided distinguished name
     * @throws NamingException if the updn and ndn indices cannot be accessed
     */
    public abstract String getEntryUpdn( String dn ) throws NamingException;
    public abstract Attributes lookup( BigInteger id ) throws NamingException;
    public abstract void delete( BigInteger id ) throws NamingException;
    public abstract NamingEnumeration list( BigInteger id ) throws NamingException;
    public abstract int getChildCount( BigInteger id ) throws NamingException;
    public abstract Attributes getSuffixEntry() throws NamingException;
    public abstract void setProperty( String key, String value ) throws NamingException;
    public abstract String getProperty( String key ) throws NamingException;
    public abstract Iterator getUserIndices();
    public abstract Iterator getSystemIndices();
    public abstract Attributes getIndices( BigInteger id ) throws NamingException;

    /**
     * Gets the count of the total number of entries in the database.
     *
     * TODO shouldn't this be a BigInteger instead of an int? 
     * 
     * @return the number of entries in the database 
     * @throws NamingException if there is a failure to read the count
     */
    public abstract int count() throws NamingException;
}
