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


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.naming.ConfigurationException;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;

import org.apache.ldap.common.MultiException;
import org.apache.ldap.common.NotImplementedException;
import org.apache.ldap.common.exception.LdapNameNotFoundException;
import org.apache.ldap.common.filter.ExprNode;
import org.apache.ldap.common.filter.PresenceNode;
import org.apache.ldap.common.message.LockableAttributeImpl;
import org.apache.ldap.common.message.LockableAttributes;
import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.ldap.common.name.LdapName;
import org.apache.ldap.common.util.DateUtils;
import org.apache.ldap.common.util.NamespaceTools;
import org.apache.ldap.common.util.SingletonEnumeration;
import org.apache.ldap.server.configuration.ContextPartitionConfiguration;
import org.apache.ldap.server.configuration.MutableContextPartitionConfiguration;
import org.apache.ldap.server.jndi.ContextFactoryConfiguration;
import org.apache.ldap.server.partition.impl.btree.jdbm.JdbmContextPartition;

                                
/**
 * A nexus for partitions dedicated for storing entries specific to a naming
 * context.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class DefaultContextPartitionNexus extends ContextPartitionNexus
{
    /** the vendorName string proudly set to: Apache Software Foundation*/
    private static final String ASF = "Apache Software Foundation";

    /** the vendorName DSE operational attribute */
    private static final String VENDORNAME_ATTR = "vendorName";

    /** the namingContexts DSE operational attribute */
    private static final String NAMINGCTXS_ATTR = "namingContexts";

    /** the closed state of this partition */
    private boolean initialized;

    /** the system backend */
    private ContextPartition system;

    /** the backends keyed by normalized suffix strings */
    private HashMap partitions = new HashMap();

    /** the read only rootDSE attributes */
    private final Attributes rootDSE;


    /**
     * Creates the root nexus singleton of the entire system.  The root DSE has
     * several attributes that are injected into it besides those that may
     * already exist.  As partitions are added to the system more namingContexts
     * attributes are added to the rootDSE.
     *
     * @see <a href="http://www.faqs.org/rfcs/rfc3045.html">Vendor Information</a>
     */
    public DefaultContextPartitionNexus( Attributes rootDSE )
    {
        // setup that root DSE
        this.rootDSE = rootDSE;
        Attribute attr = new LockableAttributeImpl( "subschemaSubentry" );
        attr.add( "cn=schema,ou=system" );
        rootDSE.put( attr );

        attr = new LockableAttributeImpl( "supportedLDAPVersion" );
        rootDSE.put( attr );
        attr.add( "3" );

        attr = new LockableAttributeImpl( "objectClass" );
        rootDSE.put( attr );
        attr.add( "top" );
        attr.add( "extensibleObject" );

        attr = new LockableAttributeImpl( NAMINGCTXS_ATTR );
        rootDSE.put( attr );

        attr = new LockableAttributeImpl( VENDORNAME_ATTR );
        attr.add( ASF );
        rootDSE.put( attr );
    }


    public void init( ContextFactoryConfiguration factoryCfg, ContextPartitionConfiguration cfg ) throws NamingException
    {
        // NOTE: We ignore ContextPartitionConfiguration parameter here.
        if( initialized )
        {
            return;
        }
        
        List initializedPartitions = new ArrayList();
        initializeSystemPartition( factoryCfg );
        initializedPartitions.add( system );
        
        Iterator i = factoryCfg.getStartupConfiguration().getContextPartitionConfigurations().iterator();
        try
        {
            while( i.hasNext() )
            {
                cfg = ( ContextPartitionConfiguration ) i.next();
                ContextPartition partition = cfg.getContextPartition();
                
                // Turn on default indices
                MutableContextPartitionConfiguration mcfg =
                    new MutableContextPartitionConfiguration();
                mcfg.setName( cfg.getName() );
                mcfg.setSuffix( cfg.getSuffix() );
                mcfg.setContextEntry( cfg.getContextEntry() );
                mcfg.setContextPartition( partition );
                
                Set indexedAttrs = cfg.getIndexedAttributes();
                indexedAttrs.add( Oid.ALIAS );
                indexedAttrs.add( Oid.EXISTANCE );
                indexedAttrs.add( Oid.HIERARCHY );
                indexedAttrs.add( Oid.NDN );
                indexedAttrs.add( Oid.ONEALIAS );
                indexedAttrs.add( Oid.SUBALIAS );
                indexedAttrs.add( Oid.UPDN );
                mcfg.setIndexedAttributes( indexedAttrs );
                
                partition.init( factoryCfg, mcfg );
                initializedPartitions.add( 0, partition );
                register( partition );
            }
            initialized = true;
        }
        finally
        {
            if( !initialized )
            {
                i = initializedPartitions.iterator();
                while( i.hasNext() )
                {
                    ContextPartition partition = ( ContextPartition ) i.next();
                    i.remove();
                    try
                    {
                        partition.destroy();
                    }
                    catch( Exception e )
                    {
                        e.printStackTrace();
                    }
                    finally
                    {
                        unregister( partition );
                    }
                }
            }
        }
    }


    private void initializeSystemPartition( ContextFactoryConfiguration factoryCfg ) throws NamingException
    {
        // initialize system partition first
        MutableContextPartitionConfiguration systemCfg = new MutableContextPartitionConfiguration();
        system = new JdbmContextPartition(); // using default implementation.
        systemCfg.setName( "system" );
        systemCfg.setSuffix( ContextPartitionNexus.SYSTEM_PARTITION_SUFFIX );
        systemCfg.setContextPartition( system );
        
        // Add indexed attributes for system partition
        Set indexedSystemAttrs = new HashSet();
        indexedSystemAttrs.add( Oid.ALIAS );
        indexedSystemAttrs.add( Oid.EXISTANCE );
        indexedSystemAttrs.add( Oid.HIERARCHY );
        indexedSystemAttrs.add( Oid.NDN );
        indexedSystemAttrs.add( Oid.ONEALIAS );
        indexedSystemAttrs.add( Oid.SUBALIAS );
        indexedSystemAttrs.add( Oid.UPDN );
        systemCfg.setIndexedAttributes( indexedSystemAttrs );
        
        // Add context entry for system partition
        Attributes systemEntry = new BasicAttributes();
        Attribute objectClassAttr = new BasicAttribute( "objectClass" );
        objectClassAttr.add( "top" );
        objectClassAttr.add( "organizationalUnit" );
        systemEntry.put( objectClassAttr );
        systemEntry.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL ) ;
        systemEntry.put( "createTimestamp", DateUtils.getGeneralizedTime() ) ;
        systemEntry.put(
                NamespaceTools.getRdnAttribute( ContextPartitionNexus.SYSTEM_PARTITION_SUFFIX ),
                NamespaceTools.getRdnValue( ContextPartitionNexus.SYSTEM_PARTITION_SUFFIX ) ) ;
        systemCfg.setContextEntry( systemEntry );

        system.init( factoryCfg, systemCfg );
        register( system );
    }


    public boolean isInitialized()
    {
        return initialized;
    }


    public synchronized void destroy()
    {
        if ( !initialized )
        {
            return;
        }

        MultiException error = null;

        Iterator list = this.partitions.values().iterator();

        // make sure this loop is not fail fast so all backing stores can
        // have an attempt at closing down and synching their cached entries
        while ( list.hasNext() )
        {
            ContextPartition partition = ( ContextPartition ) list.next();

            try
            {
                partition.sync();
                partition.destroy();
            }
            catch ( NamingException e )
            {
                e.printStackTrace();

                if ( error == null )
                {
                    error = new MultiException( "Grouping many exceptions on root nexus close()" );
                }

                // @todo really need to send this info to a monitor
                error.addThrowable( e );
            }
        }

        initialized = false;

        if ( error != null )
        {
            String msg = "Encountered failures while performing a close() operation on backing stores";

            NamingException total = new NamingException( msg );

            total.setRootCause( error );
            total.printStackTrace();
        }
    }


    /**
     * @see ContextPartition#sync()
     */
    public void sync() throws NamingException
    {
        MultiException error = null;

        Iterator list = this.partitions.values().iterator();

        while ( list.hasNext() )
        {
            ContextPartition store = ( ContextPartition ) list.next();

            try
            {
                store.sync();
            }
            catch ( NamingException e )
            {
                e.printStackTrace();

                if ( error == null )
                {
                    error = new MultiException( "Grouping many exceptions on root nexus sync()" );
                }

                // @todo really need to send this info to a monitor
                error.addThrowable( e );
            }
        }

        if ( error != null )
        {
            String msg = "Encountered failures while performing a sync() operation on backing stores";

            NamingException total = new NamingException( msg );

            total.setRootCause( error );
        }
    }


    // ------------------------------------------------------------------------
    // BackendNexus Interface Method Implementations
    // ------------------------------------------------------------------------
    
    
    public ContextPartition getSystemPartition()
    {
        return system;
    }

    /**
     * @see ContextPartitionNexus#getLdapContext()
     */
    public LdapContext getLdapContext() 
    {
        throw new NotImplementedException();
    }


    /**
     * @see ContextPartitionNexus#getMatchedName(javax.naming.Name, boolean)
     */
    public Name getMatchedName( Name dn, boolean normalized ) throws NamingException
    {
        dn = ( Name ) dn.clone();

        while ( dn.size() > 0 )
        {
            if ( hasEntry( dn ) )
            {
                return dn;
            }

            dn = dn.getSuffix( 1 );
        }

        return dn;
    }


    public Name getSuffix( boolean normalized )
    {
        return new LdapName();
    }


    /**
     * @see org.apache.ldap.server.partition.ContextPartitionNexus#getSuffix(javax.naming.Name, boolean)
     */
    public Name getSuffix( Name dn, boolean normalized ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        return backend.getSuffix( normalized );
    }


    /**
     * @see org.apache.ldap.server.partition.ContextPartitionNexus#listSuffixes(boolean)
     */
    public Iterator listSuffixes( boolean normalized ) throws NamingException
    {
        return Collections.unmodifiableSet( partitions.keySet() ).iterator();
    }


    public Attributes getRootDSE() 
    {
        return rootDSE;
    }


    /**
     * Registers an ContextPartition with this BackendManager.  Called by each
     * ContextPartition implementation after it has started to register for
     * backend operation calls.  This method effectively puts the 
     * ContextPartition's naming context online.
     *
     * Operations against the naming context should result in an LDAP BUSY
     * result code in the returnValue if the naming context is not online.
     *
     * @param partition ContextPartition component to register with this
     * BackendNexus.
     * @throws ConfigurationException 
     */
    private void register( ContextPartition partition ) throws NamingException
    {
        String key = partition.getSuffix( true ).toString();
        if( partitions.containsKey( key ) )
        {
            throw new ConfigurationException( "Duplicate partition suffix: " + key );
        }
        partitions.put( key, partition );

        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
        namingContexts.add( partition.getSuffix( false ).toString() );
    }


    /**
     * Unregisters an ContextPartition with this BackendManager.  Called for each
     * registered Backend right befor it is to be stopped.  This prevents
     * protocol server requests from reaching the Backend and effectively puts
     * the ContextPartition's naming context offline.
     *
     * Operations against the naming context should result in an LDAP BUSY
     * result code in the returnValue if the naming context is not online.
     *
     * @param partition ContextPartition component to unregister with this
     * BackendNexus.
     */
    private void unregister( ContextPartition partition ) throws NamingException
    {
        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
        namingContexts.remove( partition.getSuffix( false ).toString() );
        partitions.remove( partition.getSuffix( true ).toString() );
    }


    // ------------------------------------------------------------------------
    // Backend Interface Method Implementations
    // ------------------------------------------------------------------------
    
    
    /**
     * @see ContextPartition#delete(javax.naming.Name)
     */
    public void delete( Name dn ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        backend.delete( dn );
    }


    /**
     * Looks up the backend corresponding to the entry first, then checks to
     * see if the entry already exists.  If so an exception is thrown.  If not
     * the add operation against the backend proceeds.  This check is performed
     * here so backend implementors do not have to worry about performing these
     * kinds of checks.
     *
     * @see org.apache.ldap.server.partition.ContextPartition#add(String, Name, Attributes)
     */
    public void add( String updn, Name dn, Attributes an_entry ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        backend.add( updn, dn, an_entry );
    }


    /**
     * @see ContextPartition#modify(Name, int,Attributes)
     */
    public void modify( Name dn, int modOp, Attributes mods ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        backend.modify( dn, modOp, mods );
    }


    /**
     * @see ContextPartition#modify(javax.naming.Name,
     * javax.naming.directory.ModificationItem[])
     */
    public void modify( Name dn, ModificationItem[] mods ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        backend.modify( dn, mods );
    }

    
    /**
     * @see ContextPartition#list(javax.naming.Name)
     */
    public NamingEnumeration list( Name base ) throws NamingException
    {
        ContextPartition backend = getBackend( base );

        return backend.list( base );
    }
    

    /**
     * @see ContextPartition#search(Name, Map, ExprNode, SearchControls)
     */
    public NamingEnumeration search( Name base, Map env, ExprNode filter, SearchControls searchCtls )
            throws NamingException
    {

        if ( base.size() == 0 )
        {
            boolean isObjectScope = searchCtls.getSearchScope() == SearchControls.OBJECT_SCOPE;

            boolean isSearchAll = ( ( PresenceNode ) filter ).getAttribute().equalsIgnoreCase( "objectclass" );

            /*
             * if basedn is "", filter is "(objectclass=*)" and scope is object
             * then we have a request for the rootDSE
             */
            if ( filter instanceof PresenceNode && isObjectScope && isSearchAll )
            {
                Attributes attrs = ( Attributes ) getRootDSE().clone();

                String[] ids = searchCtls.getReturningAttributes();

                if ( ids != null && ids.length > 0 )
                {
                    boolean doSwap = true;

                    Attributes askedFor = new LockableAttributesImpl();

                    for ( int ii = 0; ii < ids.length; ii++ )
                    {
                        if ( ids[ii].trim().equals( "*" ) )
                        {
                            doSwap = false;

                            break;
                        }

                        if ( attrs.get( ids[ii] ) != null )
                        {
                            askedFor.put( attrs.get( ids[ii] ) );
                        }
                    }

                    if ( doSwap )
                    {
                        attrs = askedFor;
                    }
                }

                SearchResult result = new SearchResult( "", null, attrs, false );

                return new SingletonEnumeration( result );
            }

            throw new LdapNameNotFoundException();
        }

        ContextPartition backend = getBackend( base );

        return backend.search( base, env, filter, searchCtls );
    }


    /**
     * @see ContextPartition#lookup(javax.naming.Name)
     */
    public Attributes lookup( Name dn )  throws NamingException
    {
        if ( dn.size() == 0 )
        {
            LockableAttributes retval = ( LockableAttributes ) rootDSE.clone();

            retval.setLocked( true );

            return retval;
        }

        ContextPartition backend = getBackend( dn );

        return backend.lookup( dn );
    }


    /**
     * @see org.apache.ldap.server.partition.ContextPartition#lookup(javax.naming.Name, String[])
     */
    public Attributes lookup( Name dn, String[] attrIds )  throws NamingException
    {
        if ( dn.size() == 0 )
        {
            LockableAttributes retval = new LockableAttributesImpl();

            NamingEnumeration list = rootDSE.getIDs();

            while ( list.hasMore() )
            {
                String id = ( String ) list.next();

                Attribute attr = rootDSE.get( id );

                retval.put( ( Attribute ) attr.clone() );
            }

            retval.setLocked( true );

            return retval;
        }

        ContextPartition backend = getBackend( dn );

        return backend.lookup( dn, attrIds );
    }


    /**
     * @see ContextPartition#hasEntry(javax.naming.Name)
     */
    public boolean hasEntry( Name dn ) throws NamingException
    {
        if ( dn.size() == 0 )
        {
            return true;
        }

        ContextPartition backend = getBackend( dn );

        return backend.hasEntry( dn );
    }

    
    /**
     * @see ContextPartition#isSuffix(javax.naming.Name)
     */
    public boolean isSuffix( Name dn )
    {
        return partitions.containsKey( dn.toString() );
    }

    
    /**
     * @see ContextPartition#modifyRn(Name, String, boolean)
     */
    public void modifyRn( Name dn, String newRdn, boolean deleteOldRdn ) throws NamingException
    {
        ContextPartition backend = getBackend( dn );

        backend.modifyRn( dn, newRdn, deleteOldRdn );
    }
    
    
    /**
     * @see ContextPartition#move(Name, Name)
     */
    public void move( Name oriChildName, Name newParentName ) throws NamingException
    {
        ContextPartition backend = getBackend( oriChildName );

        backend.move( oriChildName, newParentName );
    }
    
    
    /**
     * @see ContextPartition#move(javax.naming.Name,
     * javax.naming.Name, java.lang.String, boolean)
     */
    public void move( Name oldChildDn, Name newParentDn, String newRdn,
        boolean deleteOldRdn ) throws NamingException
    {
        ContextPartition backend = getBackend( oldChildDn );

        backend.move( oldChildDn, newParentDn, newRdn, deleteOldRdn );
    }

    
    // ------------------------------------------------------------------------
    // Private Methods
    // ------------------------------------------------------------------------


    /**
     * Gets the backend partition associated with a normalized dn.
     *
     * @param dn the normalized distinguished name to resolve to a backend
     * @return the backend partition associated with the normalized dn
     * @throws NamingException if the name cannot be resolved to a backend
     */
    private ContextPartition getBackend( Name dn ) throws NamingException
    {
        Name clonedDn = ( Name ) dn.clone();

        while ( clonedDn.size() > 0 )
        {
            if ( partitions.containsKey( clonedDn.toString() ) )
            {
                return ( ContextPartition ) partitions.get( clonedDn.toString() );
            }
            
            clonedDn.remove( clonedDn.size() - 1 );
        }
        
        throw new NameNotFoundException( dn.toString() );
    }
}
