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

import java.util.Hashtable;
import java.util.Iterator;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;

import org.apache.ldap.common.exception.LdapAuthenticationNotSupportedException;
import org.apache.ldap.common.exception.LdapConfigurationException;
import org.apache.ldap.common.exception.LdapNoPermissionException;
import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.ldap.common.message.ResultCodeEnum;
import org.apache.ldap.common.name.DnParser;
import org.apache.ldap.common.name.LdapName;
import org.apache.ldap.common.name.NameComponentNormalizer;
import org.apache.ldap.common.util.DateUtils;
import org.apache.ldap.server.configuration.Configuration;
import org.apache.ldap.server.configuration.ConfigurationException;
import org.apache.ldap.server.configuration.StartupConfiguration;
import org.apache.ldap.server.interceptor.InterceptorChain;
import org.apache.ldap.server.partition.ContextPartitionNexus;
import org.apache.ldap.server.partition.DefaultContextPartitionNexus;
import org.apache.ldap.server.schema.AttributeTypeRegistry;
import org.apache.ldap.server.schema.ConcreteNameComponentNormalizer;
import org.apache.ldap.server.schema.GlobalRegistries;
import org.apache.ldap.server.schema.bootstrap.BootstrapRegistries;
import org.apache.ldap.server.schema.bootstrap.BootstrapSchemaLoader;


/**
 * Default implementation of {@link ContextFactoryService}.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
class DefaultContextFactoryService implements ContextFactoryService
{
    private final ContextFactoryConfiguration configuration = new DefaultContextFactoryConfiguration( this );

    private ContextFactoryServiceListener serviceListener;
    
    /** the initial context environment that fired up the backend subsystem */
    private Hashtable environment;
    
    /** the configuration */
    private StartupConfiguration startupConfiguration;

    /** the registries for system schema objects */
    private GlobalRegistries globalRegistries;

    /** the root nexus */
    private DefaultContextPartitionNexus partitionNexus;

    /** whether or not server is started for the first time */
    private boolean firstStart;

    /** The interceptor (or interceptor chain) for this service */
    private InterceptorChain interceptorChain;
    
    /** whether or not this instance has been shutdown */
    private boolean started = false;


    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------

    /**
     * Creates a new instance.
     */
    public DefaultContextFactoryService()
    {
        // Register shutdown hook.
        Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() {
            public void run()
            {
                try
                {
                    shutdown();
                }
                catch( NamingException e )
                {
                    e.printStackTrace();
                }
            }
        }, "ApacheDS Shutdown Hook" ) );
    }

    // ------------------------------------------------------------------------
    // BackendSubsystem Interface Method Implemetations
    // ------------------------------------------------------------------------

    public Context getJndiContext( String rootDN ) throws NamingException
    {
        return this.getJndiContext( null, null, "none", rootDN );
    }

    public synchronized Context getJndiContext( String principal, byte[] credential, String authentication, String rootDN ) throws NamingException
    {
        checkSecuritySettings( principal, credential, authentication );
        
        if ( !started )
        {
            return new DeadContext();
        }
        
        Hashtable environment = getEnvironment();
        if( principal != null )
        {
            environment.put( Context.SECURITY_PRINCIPAL, principal );
        }
        
        if( credential != null )
        {
            environment.put( Context.SECURITY_CREDENTIALS, credential );
        }
        
        if( authentication != null )
        {
            environment.put( Context.SECURITY_AUTHENTICATION, authentication );
        }
        
        if( rootDN == null )
        {
            rootDN = "";
        }
        environment.put( Context.PROVIDER_URL, rootDN );

        return new ServerLdapContext( this, environment );
    }

    public synchronized void startup( ContextFactoryServiceListener listener, Hashtable env ) throws NamingException
    {
        if( started )
        {
            return;
        }

        StartupConfiguration cfg = ( StartupConfiguration ) Configuration.toConfiguration( env );

        env.put( Context.PROVIDER_URL, "" );
        
        try
        {
            cfg.validate();
        }
        catch( ConfigurationException e )
        {
            NamingException ne = new LdapConfigurationException( "Invalid configuration." );
            ne.initCause( e );
            throw ne;
        }

        this.environment = env;
        this.startupConfiguration = cfg;
        
        listener.beforeStartup( this );
        try
        {
            initialize();
            firstStart = createBootstrapEntries();
            createTestEntries();
            this.serviceListener = listener;
            started = true;
        }
        finally
        {
            listener.afterStartup( this );
        }
    }

    public synchronized void sync() throws NamingException
    {
        if ( !started )
        {
            return;
        }

        serviceListener.beforeSync( this );
        try
        {
            this.partitionNexus.sync();
        }
        finally
        {
            serviceListener.afterSync( this );
        }
    }


    public synchronized void shutdown() throws NamingException
    {
        if ( !started )
        {
            return;
        }

        serviceListener.beforeShutdown( this );
        try
        {
            this.partitionNexus.sync();
            this.partitionNexus.destroy();
            this.interceptorChain.destroy();
            this.started = false;
        }
        finally
        {
            environment = null;
            interceptorChain = null;
            startupConfiguration = null;
            serviceListener.afterShutdown( this );
        }
    }
    
    public ContextFactoryConfiguration getConfiguration()
    {
        return configuration;
    }
    
    
    public Hashtable getEnvironment()
    {
        return ( Hashtable ) environment.clone();
    }
    
    public ContextFactoryServiceListener getServiceListener()
    {
        return serviceListener;
    }
    
    public StartupConfiguration getStartupConfiguration()
    {
        return startupConfiguration;
    }
    
    public GlobalRegistries getGlobalRegistries()
    {
        return globalRegistries;
    }

    public ContextPartitionNexus getPartitionNexus()
    {
        return partitionNexus;
    }
    
    public InterceptorChain getInterceptorChain()
    {
        return interceptorChain;
    }
    
    public boolean isFirstStart()
    {
        return firstStart;
    }
    
    public boolean isStarted()
    {
        return started;
    }
    
    /**
     * Checks to make sure security environment parameters are set correctly.
     *
     * @throws javax.naming.NamingException if the security settings are not correctly configured.
     */
    private void checkSecuritySettings( String principal, byte[] credential, String authentication ) throws NamingException
    {
        if( authentication == null )
        {
            authentication = "";
        }
        
        /*
         * If bind is simple make sure we have the credentials and the
         * principal name set within the environment, otherwise complain
         */
        if ( "simple".equalsIgnoreCase( authentication ) )
        {
            if ( credential == null )
            {
                throw new LdapConfigurationException( "missing required "
                        + Context.SECURITY_CREDENTIALS + " property for simple authentication" );
            }

            if ( principal == null )
            {
                throw new LdapConfigurationException( "missing required "
                        + Context.SECURITY_PRINCIPAL + " property for simple authentication" );
            }
        }
        /*
         * If bind is none make sure credentials and the principal
         * name are NOT set within the environment, otherwise complain
         */
        else if ( "none".equalsIgnoreCase( authentication ) )
        {
            if ( credential != null )
            {
                throw new LdapConfigurationException( "ambiguous bind "
                        + "settings encountered where bind is anonymous yet "
                        + Context.SECURITY_CREDENTIALS + " property is set" );
            }
            if ( principal != null )
            {
                throw new LdapConfigurationException( "ambiguous bind "
                        + "settings encountered where bind is anonymous yet "
                        + Context.SECURITY_PRINCIPAL + " property is set" );
            }
            
            if( !startupConfiguration.isAllowAnonymousAccess() )
            {
                throw new LdapNoPermissionException( "Anonymous access disabled." );
            }
        }
        else
        {
            /*
             * If bind is anything other than simple or none we need to
             * complain because SASL is not a supported auth method yet
             */
            throw new LdapAuthenticationNotSupportedException( "Unknown authentication type: '" + authentication + "'", ResultCodeEnum.AUTHMETHODNOTSUPPORTED );
        }
    }


    /**
     * Returns true if we had to create the bootstrap entries on the first
     * start of the server.  Otherwise if all entries exist, meaning none
     * had to be created, then we are not starting for the first time.
     *
     * @throws javax.naming.NamingException
     */
    private boolean createBootstrapEntries() throws NamingException
    {
        boolean firstStart = false;

        // -------------------------------------------------------------------
        // create admin entry
        // -------------------------------------------------------------------

        /*
         * If the admin entry is there, then the database was already created
         */
        if ( !partitionNexus.hasEntry( ContextPartitionNexus.getAdminName() ) )
        {
            firstStart = true;

            Attributes attributes = new LockableAttributesImpl();
            attributes.put( "objectClass", "top" );
            attributes.put( "objectClass", "person" );
            attributes.put( "objectClass", "organizationalPerson" );
            attributes.put( "objectClass", "inetOrgPerson" );
            attributes.put( "uid", ContextPartitionNexus.ADMIN_UID );
            attributes.put( "userPassword", ContextPartitionNexus.ADMIN_PW );
            attributes.put( "displayName", "Directory Superuser" );
            attributes.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL );
            attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
            attributes.put( "displayName", "Directory Superuser" );
            
            partitionNexus.add( ContextPartitionNexus.ADMIN_PRINCIPAL, ContextPartitionNexus.getAdminName(), attributes );
        }

        // -------------------------------------------------------------------
        // create system users area
        // -------------------------------------------------------------------

        if ( !partitionNexus.hasEntry( new LdapName( "ou=users,ou=system" ) ) )
        {
            firstStart = true;
            
            Attributes attributes = new LockableAttributesImpl();
            attributes.put( "objectClass", "top" );
            attributes.put( "objectClass", "organizationalUnit" );
            attributes.put( "ou", "users" );
            attributes.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL );
            attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );

            partitionNexus.add( "ou=users,ou=system", new LdapName( "ou=users,ou=system" ), attributes );
        }

        // -------------------------------------------------------------------
        // create system groups area
        // -------------------------------------------------------------------

        if ( !partitionNexus.hasEntry( new LdapName( "ou=groups,ou=system" ) ) )
        {
            firstStart = true;

            Attributes attributes = new LockableAttributesImpl();
            attributes.put( "objectClass", "top" );
            attributes.put( "objectClass", "organizationalUnit" );
            attributes.put( "ou", "groups" );
            attributes.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL );
            attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );

            partitionNexus.add( "ou=groups,ou=system", new LdapName( "ou=groups,ou=system" ), attributes );
        }

        // -------------------------------------------------------------------
        // create system preferences area
        // -------------------------------------------------------------------

        if ( !partitionNexus.hasEntry( new LdapName( "prefNodeName=sysPrefRoot,ou=system" ) ) )
        {
            firstStart = true;

            Attributes attributes = new LockableAttributesImpl();
            attributes.put( "objectClass", "top" );
            attributes.put( "objectClass", "prefNode" );
            attributes.put( "objectClass", "extensibleObject" );
            attributes.put( "prefNodeName", "sysPrefRoot" );
            attributes.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL );
            attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );

            LdapName dn = new LdapName( "prefNodeName=sysPrefRoot,ou=system" );

            partitionNexus.add( "prefNodeName=sysPrefRoot,ou=system", dn, attributes );
        }

        return firstStart;
    }


    private void createTestEntries() throws NamingException
    {
        /*
         * Unfortunately to test non-root user startup of the core and make sure
         * all the appropriate functionality is there we need to load more user
         * entries at startup due to a chicken and egg like problem.  The value
         * of this property is a list of attributes to be added.
         */
        Iterator i = startupConfiguration.getTestEntries().iterator();
        while( i.hasNext() )
        {
            Attributes entry = ( Attributes ) i.next();
            entry.put( "creatorsName", ContextPartitionNexus.ADMIN_PRINCIPAL );
            entry.put( "createTimestamp", DateUtils.getGeneralizedTime() );
            
            Attribute dn = entry.remove( "dn" );
            AttributeTypeRegistry registry = globalRegistries.getAttributeTypeRegistry();
            NameComponentNormalizer ncn = new ConcreteNameComponentNormalizer( registry );
            DnParser parser = new DnParser( ncn );
            Name ndn = parser.parse( ( String ) dn.get() );
            
            partitionNexus.add( ( String ) dn.get(), ndn, entry );
        }
    }

    /**
     * Kicks off the initialization of the entire system.
     *
     * @throws javax.naming.NamingException if there are problems along the way
     */
    private void initialize() throws NamingException
    {
        // --------------------------------------------------------------------
        // Load the schema here and check that it is ok!
        // --------------------------------------------------------------------

        BootstrapRegistries bootstrapRegistries = new BootstrapRegistries();

        BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
        loader.load( startupConfiguration.getBootstrapSchemas(), bootstrapRegistries );

        java.util.List errors = bootstrapRegistries.checkRefInteg();
        if ( !errors.isEmpty() )
        {
            NamingException e = new NamingException();

            e.setRootCause( ( Throwable ) errors.get( 0 ) );

            throw e;
        }

        globalRegistries = new GlobalRegistries( bootstrapRegistries );
        
        partitionNexus = new DefaultContextPartitionNexus( new LockableAttributesImpl() );
        partitionNexus.init( configuration, null );
        
        interceptorChain = new InterceptorChain();
        interceptorChain.init( configuration );
    }
}
