/*
 *  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.partition.impl.btree;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.apache.directory.server.core.DirectoryServiceConfiguration;
import org.apache.directory.server.core.configuration.PartitionConfiguration;
import org.apache.directory.server.core.enumeration.SearchResultEnumeration;
import org.apache.directory.server.core.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.interceptor.context.OperationContext;
import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
import org.apache.directory.server.core.partition.Oid;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.core.partition.impl.btree.gui.PartitionViewer;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.server.schema.registries.OidRegistry;
import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.shared.ldap.exception.LdapContextNotEmptyException;
import org.apache.directory.shared.ldap.exception.LdapNameNotFoundException;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.schema.AttributeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An abstract {@link Partition} that uses general BTree operations.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public abstract class BTreePartition implements Partition
{
    private static final Logger log = LoggerFactory.getLogger( BTreePartition.class );

    /** the search engine used to search the database */
    private SearchEngine searchEngine = null;
    private Optimizer optimizer = new NoOpOptimizer();
    
    protected AttributeTypeRegistry attributeTypeRegistry = null;
    protected OidRegistry oidRegistry = null;


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

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

    
    /**
     * Allows for schema entity registries to be swapped out during runtime.  This is 
     * primarily here to facilitate the swap out of a temporary bootstrap registry.  
     * Registry changes require swapping out the search engine used by a partition 
     * since the registries are used by elements in the search engine.
     * 
     * @param registries the schema entity registries
     */
    public void initRegistries( Registries registries )
    {
        initRegistries1( registries );
    }
    
    
    /**
     * This should be called second after initializing the optimizer with 
     * initOptimizer0.  This is the same as calling initRegistries() 
     * (initRegistries actually calls initRegistries1) except it is protected 
     * to hide the '1' at the end of the method name.  The '1' indicates it 
     * is the 2nd thing that must be executed during initialization.
     * 
     * @param registries the schema entity registries
     */
    protected void initRegistries1( Registries registries )
    {
        attributeTypeRegistry = registries.getAttributeTypeRegistry();
        oidRegistry = registries.getOidRegistry();
        ExpressionEvaluator evaluator = new ExpressionEvaluator( this, oidRegistry, attributeTypeRegistry );
        ExpressionEnumerator enumerator = new ExpressionEnumerator( this, attributeTypeRegistry, evaluator );
        this.searchEngine = new DefaultSearchEngine( this, evaluator, enumerator, optimizer );
    }
    
    
    /**
     * Use this method to initialize the indices.  Only call this after
     * the registries and the optimizer have been enabled.  The '2' at the end
     * shows this is the 3rd init method called in the init sequence.
     * 
     * @param indices
     * @throws NamingException
     */
    protected void initIndices2(Set indices ) throws NamingException
    {
        Set<String> sysOidSet = new HashSet<String>();
        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 );

        // Used to calculate the system indices we must automatically add
        Set<String> customAddedSystemIndices = new HashSet<String>();
        
        for ( Iterator ii = indices.iterator(); ii.hasNext(); /**/ )
        {
            /*
             * NOTE
             * ====
             * 
             * The object returned by the indexedAttributes property
             * of the configuration may include just a simple set of <String> 
             * names for the attributes being index OR may include a set 
             * of IndexConfiguration objects.
             * 
             * If the objects are strings extra information about the
             * cacheSize of an index is not available and so the default is
             * used.  If an IndexConfiguration is available then the custom
             * cacheSize is used.
             */
            
            Object nextObject = ii.next();
            String name = null;
            int cacheSize = IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE;
            int numDupLimit = IndexConfiguration.DEFAULT_DUPLICATE_LIMIT;
            
            // no custom cacheSize info is available so default sticks
            if ( nextObject instanceof String ) 
            {
                name = ( String ) nextObject;
                log.warn( "Using default cache size of {} for index on attribute {}", 
                    new Integer( cacheSize ), name );
            }
            // custom cache size is used
            else if ( nextObject instanceof IndexConfiguration )
            {
                IndexConfiguration indexConfiguration = ( IndexConfiguration ) nextObject;
                name = indexConfiguration.getAttributeId();
                cacheSize = indexConfiguration.getCacheSize();
                numDupLimit = indexConfiguration.getDuplicateLimit();
                
                if ( cacheSize <= 0 ) 
                {
                    log.warn( "Cache size {} for index on attribute is null or negative. Using default value.", 
                        new Integer(cacheSize), name );
                    cacheSize = IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE;
                }
                else
                {
                    log.info( "Using cache size of {} for index on attribute {}", 
                        new Integer( cacheSize ), name );
                }
                
                if ( cacheSize <= 0 ) 
                {
                    log.warn( "Duplicate limit {} for index on attribute is null or negative. Using default value.", 
                        new Integer(numDupLimit), name );
                    cacheSize = IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE;
                }
                else
                {
                    log.info( "Using duplicate limit of {} for index on attribute {}", 
                        new Integer( numDupLimit ), name );
                }
            }
            
            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, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.EXISTANCE );
                }
                else if ( oid.equals( Oid.HIERARCHY ) )
                {
                    setHierarchyIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.HIERARCHY );
                }
                else if ( oid.equals( Oid.UPDN ) )
                {
                    setUpdnIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.UPDN );
                }
                else if ( oid.equals( Oid.NDN ) )
                {
                    setNdnIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.NDN );
                }
                else if ( oid.equals( Oid.ONEALIAS ) )
                {
                    setOneAliasIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.ONEALIAS );
                }
                else if ( oid.equals( Oid.SUBALIAS ) )
                {
                    setSubAliasIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.SUBALIAS);
                }
                else if ( oid.equals( Oid.ALIAS ) )
                {
                    setAliasIndexOn( type, cacheSize, numDupLimit );
                    customAddedSystemIndices.add( Oid.ALIAS );
                }
                else
                {
                    throw new NamingException( "Unidentified system index " + oid );
                }
            }
            else
            {
                addIndexOn( type, cacheSize, numDupLimit );
            }
        }
        
        // -------------------------------------------------------------------
        // Add all system indices that were not custom configured by iterating
        // through all system index oids and checking of that index is 
        // contained within the customAddedSystemIndices set.  If it is not
        // contained in this set then the system index was not custom 
        // configured above and must be configured with defaults below.
        // -------------------------------------------------------------------
        
        for ( Iterator ii = sysOidSet.iterator(); ii.hasNext(); /**/ )
        {
            String systemIndexName = ( String ) ii.next();
            if ( ! customAddedSystemIndices.contains( systemIndexName ) )
            {
                AttributeType type = attributeTypeRegistry.lookup( systemIndexName );
                log.warn( "Using default cache size of {} for index on attribute {}", 
                    new Integer( IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE ), systemIndexName );
                if ( systemIndexName.equals( Oid.EXISTANCE ) )
                {
                    setExistanceIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE, 
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.HIERARCHY ) )
                {
                    setHierarchyIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.UPDN ) )
                {
                    setUpdnIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.NDN ) )
                {
                    setNdnIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.ONEALIAS ) )
                {
                    setOneAliasIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.SUBALIAS ) )
                {
                    setSubAliasIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else if ( systemIndexName.equals( Oid.ALIAS ) )
                {
                    setAliasIndexOn( type, IndexConfiguration.DEFAULT_INDEX_CACHE_SIZE,
                        IndexConfiguration.DEFAULT_DUPLICATE_LIMIT );
                }
                else
                {
                    throw new NamingException( "Unidentified system index " + systemIndexName );
                }
            }
        }
    }

    
    /**
     * Called last (4th) to check if the suffix entry has been created on disk,
     * and if not it is created.
     *  
     * @param suffix
     * @param entry
     * @throws NamingException
     */
    protected void initSuffixEntry3( String suffix, Attributes entry ) throws NamingException
    {
        // add entry for context, if it does not exist
        Attributes suffixOnDisk = getSuffixEntry();
        if ( suffixOnDisk == null )
        {
            LdapDN dn = new LdapDN( suffix );
            LdapDN normalizedSuffix = LdapDN.normalize( dn, attributeTypeRegistry.getNormalizerMapping() );
            add( new AddOperationContext( normalizedSuffix, entry ) );
        }
    }

    
    /**
     * Call this first in the init sequence to initialize the optimizer.
     * 
     * @param cfg
     */
    protected void initOptimizer0( PartitionConfiguration cfg )
    {
        if ( cfg instanceof BTreePartitionConfiguration )
        {
            if ( ( ( BTreePartitionConfiguration ) cfg ).isOptimizerEnabled() )
            {
                optimizer = new DefaultOptimizer( this );
            }
        }
    }

    
    public void init( DirectoryServiceConfiguration factoryCfg, PartitionConfiguration cfg )
        throws NamingException
    {
        initOptimizer0( cfg );
        initRegistries1( factoryCfg.getRegistries() );
        initIndices2( cfg.getIndexedAttributes() );
        initSuffixEntry3( cfg.getSuffix(), 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( OperationContext opContext ) throws NamingException
    {
    	LdapDN dn = opContext.getDn();
    	
        Long id = getEntryId( dn.getNormName() );

        // 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( OperationContext opContext ) throws NamingException;


    public abstract void modify( OperationContext opContext ) throws NamingException;


    private static final String[] ENTRY_DELETED_ATTRS = new String[] { "entrydeleted" };
    
    public NamingEnumeration list( OperationContext opContext ) throws NamingException
    {
        SearchResultEnumeration list;
        list = new BTreeSearchResultEnumeration( ENTRY_DELETED_ATTRS, list( getEntryId( opContext.getDn().getNormName() ) ),
            this, attributeTypeRegistry );
        return list;
    }


    public NamingEnumeration<SearchResult> search( OperationContext opContext )
        throws NamingException
    {
        SearchControls searchCtls = ((SearchOperationContext)opContext).getSearchControls();
        String[] attrIds = searchCtls.getReturningAttributes();
        NamingEnumeration underlying = null;

        underlying = searchEngine.search( 
            opContext.getDn(), 
            ((SearchOperationContext)opContext).getEnv(), 
            ((SearchOperationContext)opContext).getFilter(), 
            searchCtls );

        return new BTreeSearchResultEnumeration( attrIds, underlying, this, attributeTypeRegistry );
    }


    public Attributes lookup( OperationContext opContext ) throws NamingException
    {
        LookupOperationContext ctx = (LookupOperationContext)opContext;
        
        Attributes entry = lookup( getEntryId( ctx.getDn().getNormName() ) );

        if ( ( ctx.getAttrsId() == null ) || ( ctx.getAttrsId().size() == 0 ) )
        {
            return entry;
        }

        Attributes retval = new AttributesImpl();

        for ( String attrId:ctx.getAttrsId() )
        {
            Attribute attr = entry.get( attrId );

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

        return retval;
    }


    public boolean hasEntry( OperationContext opContext ) throws NamingException
    {
        return null != getEntryId( opContext.getDn().getNormName() );
    }


    public abstract void rename( OperationContext opContext ) throws NamingException;


    public abstract void move( OperationContext opContext ) throws NamingException;


    public abstract void moveAndRename( OperationContext opContext )
        throws NamingException;


    public abstract void sync() throws NamingException;


    public abstract void destroy();


    public abstract boolean isInitialized();


    public void inspect() throws Exception
    {
        PartitionViewer viewer = new PartitionViewer( this, searchEngine );
        viewer.execute();
    }


    ////////////////////
    // public abstract methods

    // ------------------------------------------------------------------------
    // Index Operations 
    // ------------------------------------------------------------------------

    public abstract void addIndexOn( AttributeType attribute, int cacheSize, int numDupLimit ) throws NamingException;


    public abstract boolean hasUserIndexOn( String attribute ) throws NamingException;


    public abstract boolean hasSystemIndexOn( String attribute ) throws NamingException;


    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, int cacheSize, int numDupLimit ) throws NamingException;


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


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


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


    /**
     * Sets the normalized distinguished name Index.
     *
     * @param attrType the ndn Index
     */
    public abstract void setNdnIndexOn( AttributeType attrType, int cacheSize, int numDupLimit ) 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, int cacheSize, int numDupLimit ) 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, int cacheSize, int numDupLimit ) throws NamingException;


    public abstract Index getUserIndex( String attribute ) throws IndexNotFoundException;


    public abstract Index getSystemIndex( String attribute ) throws IndexNotFoundException;


    public abstract Long getEntryId( String dn ) throws NamingException;


    public abstract String getEntryDn( Long id ) throws NamingException;


    public abstract Long getParentId( String dn ) throws NamingException;


    public abstract Long getParentId( Long 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( Long 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( Long id ) throws NamingException;


    public abstract void delete( Long id ) throws NamingException;


    public abstract NamingEnumeration list( Long id ) throws NamingException;


    public abstract int getChildCount( Long 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( Long 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;
}
