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


import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;

import org.apache.commons.lang.StringUtils;
import org.apache.directory.server.changepw.ChangePasswordConfiguration;
import org.apache.directory.server.changepw.ChangePasswordServer;
import org.apache.directory.server.configuration.ServerStartupConfiguration;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.jndi.CoreContextFactory;
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.server.kerberos.kdc.KdcConfiguration;
import org.apache.directory.server.kerberos.kdc.KerberosServer;
import org.apache.directory.server.kerberos.shared.store.JndiPrincipalStoreImpl;
import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
import org.apache.directory.server.ldap.ExtendedOperationHandler;
import org.apache.directory.server.ldap.LdapProtocolProvider;
import org.apache.directory.server.ntp.NtpConfiguration;
import org.apache.directory.server.ntp.NtpServer;
import org.apache.directory.server.protocol.shared.LoadStrategy;
import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
import org.apache.directory.shared.ldap.exception.LdapNamingException;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
import org.apache.directory.shared.ldap.util.StringTools;
import org.apache.mina.common.DefaultIoFilterChainBuilder;
import org.apache.mina.common.ExecutorThreadModel;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.IoFilterChainBuilder;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.WriteFuture;
import org.apache.mina.transport.socket.nio.DatagramAcceptor;
import org.apache.mina.transport.socket.nio.DatagramAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;


/**
 * Adds additional bootstrapping for server socket listeners when firing
 * up the server.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 * @see javax.naming.spi.InitialContextFactory
 */
public class ServerContextFactory extends CoreContextFactory
{
	/** Logger for this class */
    private static final Logger log = LoggerFactory.getLogger( ServerContextFactory.class.getName() );
    private static final String LDIF_FILES_DN = "ou=loadedLdifFiles,ou=configuration,ou=system";

    protected static IoAcceptor tcpAcceptor;
    protected static IoAcceptor udpAcceptor;
    protected static ThreadPoolExecutor threadPoolExecutor;
    protected static ExecutorThreadModel threadModel = ExecutorThreadModel.getInstance( "ApacheDS" );
    
    private static boolean ldapStarted;
    private static boolean ldapsStarted;
    private static KerberosServer tcpKdcServer;
    private static KerberosServer udpKdcServer;
    private static ChangePasswordServer tcpChangePasswordServer;
    private static ChangePasswordServer udpChangePasswordServer;
    private static NtpServer tcpNtpServer;
    private static NtpServer udpNtpServer;
    private DirectoryService directoryService;

    /**
     * Initialize the SocketAcceptor so that the server can accept
     * incomming requests.
     * 
     * We will start N threads, spreaded on the available CPUs.
     */
    public void beforeStartup( DirectoryService service )
    {
        int maxThreads = service.getConfiguration().getStartupConfiguration().getMaxThreads();
        threadPoolExecutor = new ThreadPoolExecutor( maxThreads, maxThreads, 60, TimeUnit.SECONDS, 
            new LinkedBlockingQueue() );
        threadModel.setExecutor( threadPoolExecutor );
        
        udpAcceptor = new DatagramAcceptor();
        tcpAcceptor = new SocketAcceptor(
            Runtime.getRuntime().availableProcessors(), threadPoolExecutor );

        this.directoryService = service;
    }


    public void afterShutdown( DirectoryService service )
    {
        ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) 
            service.getConfiguration().getStartupConfiguration();
        
        if ( ldapStarted )
        {
            stopLDAP0( cfg.getLdapPort() );
            ldapStarted = false;
        }

        if ( ldapsStarted )
        {
            stopLDAP0( cfg.getLdapsPort() );
            ldapsStarted = false;
        }

        if ( tcpKdcServer != null )
        {
            tcpKdcServer.destroy();
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of KRB5 Service (TCP) complete: " + tcpKdcServer );
            }
            
            tcpKdcServer = null;
        }

        if ( udpKdcServer != null )
        {
            udpKdcServer.destroy();
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of KRB5 Service (UDP) complete: " + udpKdcServer );
            }
            
            udpKdcServer = null;
        }

        if ( tcpChangePasswordServer != null )
        {
            tcpChangePasswordServer.destroy();
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of Change Password Service (TCP) complete: " + tcpChangePasswordServer );
            }
            
            tcpChangePasswordServer = null;
        }

        if ( udpChangePasswordServer != null )
        {
            udpChangePasswordServer.destroy();
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of Change Password Service (UDP) complete: " + udpChangePasswordServer );
            }
            
            udpChangePasswordServer = null;
        }

        if ( tcpNtpServer != null )
        {
            tcpNtpServer.destroy();
    
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of NTP Service (TCP) complete: " + tcpNtpServer );
            }
            
            tcpNtpServer = null;
        }

        if ( udpNtpServer != null )
        {
            udpNtpServer.destroy();
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of NTP Service complete: " + udpNtpServer );
            }
            
            udpNtpServer = null;
        }
    }


    public void afterStartup( DirectoryService service ) throws NamingException
    {
        ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) service.getConfiguration()
            .getStartupConfiguration();
        Hashtable env = service.getConfiguration().getEnvironment();

        loadLdifs( service );

        if ( cfg.isEnableNetworking() )
        {
            startLDAP( cfg, env );
            startLDAPS( cfg, env );
            startKerberos( cfg, env );
            startChangePassword( cfg, env );
            startNTP( cfg, env );
        }
    }


    private void ensureLdifFileBase( DirContext root )
    {
        Attributes entry = new AttributesImpl( SchemaConstants.OU_AT, "loadedLdifFiles", true );
        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC );
        entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( SchemaConstants.ORGANIZATIONAL_UNIT_OC );
        
        try
        {
            root.createSubcontext( LDIF_FILES_DN, entry );
            log.info( "Creating " + LDIF_FILES_DN );
        }
        catch ( NamingException e )
        {
            log.info( LDIF_FILES_DN + " exists" );
        }
    }

    private final static String WINDOWSFILE_ATTR = "windowsFilePath";
    private final static String UNIXFILE_ATTR = "unixFilePath";
    private final static String WINDOWSFILE_OC = "windowsFile";
    private final static String UNIXFILE_OC = "unixFile";

    private String buildProtectedFileEntry( File ldif )
    {
        StringBuffer buf = new StringBuffer();

        buf.append( File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR );
        buf.append( "=" );
        
        buf.append( StringTools.dumpHexPairs( StringTools.getBytesUtf8( getCanonical( ldif ) ) ) );
        
        buf.append( "," );
        buf.append( LDIF_FILES_DN );

        return buf.toString();
    }

    private void addFileEntry( DirContext root, File ldif ) throws NamingException
    {
		String rdnAttr = File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR;    
        String oc = File.separatorChar == '\\' ? WINDOWSFILE_OC : UNIXFILE_OC;

        Attributes entry = new AttributesImpl( rdnAttr, getCanonical( ldif ), true );
        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC );
        entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( oc );
        root.createSubcontext( buildProtectedFileEntry( ldif ), entry );
    }


    private Attributes getLdifFileEntry( DirContext root, File ldif )
    {
        try
        {
            return root.getAttributes( buildProtectedFileEntry( ldif ), new String[]
                { SchemaConstants.CREATE_TIMESTAMP_AT } );
        }
        catch ( NamingException e )
        {
            return null;
        }
    }


    private String getCanonical( File file )
    {
        String canonical = null;
        
        try
        {
            canonical = file.getCanonicalPath();
        }
        catch ( IOException e )
        {
            log.error( "could not get canonical path", e );
            return null;
        }

        return StringUtils.replace( canonical, "\\", "\\\\" );
    }


    private void loadLdifs( DirectoryService service ) throws NamingException
    {
        ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) service.getConfiguration()
            .getStartupConfiguration();

        // log and bail if property not set
        if ( cfg.getLdifDirectory() == null )
        {
            log.info( "LDIF load directory not specified.  No LDIF files will be loaded." );
            return;
        }

        // log and bail if LDIF directory does not exists
        if ( !cfg.getLdifDirectory().exists() )
        {
            log.warn( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() )
                + "' does not exist.  No LDIF files will be loaded." );
            return;
        }

        // get an initial context to the rootDSE for creating the LDIF entries
        Hashtable env = ( Hashtable ) service.getConfiguration().getEnvironment().clone();
        env.put( Context.PROVIDER_URL, "" );
        DirContext root = ( DirContext ) this.getInitialContext( env );

        // make sure the configuration area for loaded ldif files is present
        ensureLdifFileBase( root );

        // if ldif directory is a file try to load it
        if ( !cfg.getLdifDirectory().isDirectory() )
        {
            if ( log.isInfoEnabled() )
            {
                log.info( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() )
                    + "' is a file.  Will attempt to load as LDIF." );
            }
            
            Attributes fileEntry = getLdifFileEntry( root, cfg.getLdifDirectory() );
            
            if ( fileEntry != null )
            {
                String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get();
                
                if ( log.isInfoEnabled() )
                {
                    log.info( "Load of LDIF file '" + getCanonical( cfg.getLdifDirectory() )
                        + "' skipped.  It has already been loaded on " + time + "." );
                }
                
                return;
            }
            
            LdifFileLoader loader = new LdifFileLoader( root, cfg.getLdifDirectory(), cfg.getLdifFilters() );
            loader.execute();

            addFileEntry( root, cfg.getLdifDirectory() );
            return;
        }

        // get all the ldif files within the directory (should be sorted alphabetically)
        File[] ldifFiles = cfg.getLdifDirectory().listFiles( new FileFilter()
        {
            public boolean accept( File pathname )
            {
                boolean isLdif = pathname.getName().toLowerCase().endsWith( ".ldif" );
                return pathname.isFile() && pathname.canRead() && isLdif;
            }
        } );

        // log and bail if we could not find any LDIF files
        if ( ldifFiles == null || ldifFiles.length == 0 )
        {
            log.warn( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() )
                + "' does not contain any LDIF files.  No LDIF files will be loaded." );
            return;
        }

        // load all the ldif files and load each one that is loaded
        for ( int ii = 0; ii < ldifFiles.length; ii++ )
        {
            Attributes fileEntry = getLdifFileEntry( root, ldifFiles[ii] );
            if ( fileEntry != null )
            {
                String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get();
                log.info( "Load of LDIF file '" + getCanonical( ldifFiles[ii] )
                    + "' skipped.  It has already been loaded on " + time + "." );
                continue;
            }
            LdifFileLoader loader = new LdifFileLoader( root, ldifFiles[ii], cfg.getLdifFilters() );
            int count = loader.execute();
            log.info( "Loaded " + count + " entries from LDIF file '" + getCanonical( ldifFiles[ii] ) + "'" );
            if ( fileEntry == null )
            {
                addFileEntry( root, ldifFiles[ii] );
            }
        }
    }


    /**
     * Starts up the LDAP protocol provider to service LDAP requests
     *
     * @throws NamingException if there are problems starting the LDAP provider
     */
    private void startLDAP( ServerStartupConfiguration cfg, Hashtable env ) throws NamingException
    {
        // Skip if disabled
        int port = cfg.getLdapPort();
        
        if ( port < 0 )
        {
            return;
        }

        startLDAP0( cfg, env, port, new DefaultIoFilterChainBuilder() );
    }


    /**
     * Starts up the LDAPS protocol provider to service LDAPS requests
     *
     * @throws NamingException if there are problems starting the LDAPS provider
     */
    private void startLDAPS( ServerStartupConfiguration cfg, Hashtable env ) throws NamingException
    {
        // Skip if disabled
        if ( !cfg.isEnableLdaps() )
        {
            return;
        }

        // We use the reflection API in case this is not running on JDK 1.5+.
        IoFilterChainBuilder chain;
        
        try
        {
            chain = ( IoFilterChainBuilder ) Class.forName( "org.apache.directory.server.ssl.LdapsInitializer", true,
                ServerContextFactory.class.getClassLoader() ).getMethod( "init", new Class[]
                { ServerStartupConfiguration.class } ).invoke( null, new Object[]
                { cfg } );
            ldapsStarted = true;
        }
        catch ( InvocationTargetException e )
        {
            if ( e.getCause() instanceof NamingException )
            {
                throw ( NamingException ) e.getCause();
            }
            else
            {
                throw ( NamingException ) new NamingException( "Failed to load LDAPS initializer." ).initCause( e
                    .getCause() );
            }
        }
        catch ( Exception e )
        {
            throw ( NamingException ) new NamingException( "Failed to load LDAPS initializer." ).initCause( e );
        }

        startLDAP0( cfg, env, cfg.getLdapsPort(), chain );
    }


    private void startLDAP0( ServerStartupConfiguration cfg, Hashtable env, int port,
        IoFilterChainBuilder chainBuilder ) throws LdapNamingException, LdapConfigurationException
    {
        // Register all extended operation handlers.
        LdapProtocolProvider protocolProvider = new LdapProtocolProvider( cfg, ( Hashtable ) env.clone() );

        for ( Iterator i = cfg.getExtendedOperationHandlers().iterator(); i.hasNext(); )
        {
            ExtendedOperationHandler h = ( ExtendedOperationHandler ) i.next();
            protocolProvider.addExtendedOperationHandler( h );
            log.info( "Added Extended Request Handler: " + h.getOid() );
            h.setLdapProvider( protocolProvider );
            PartitionNexus nexus = directoryService.getConfiguration().getPartitionNexus();
            nexus.registerSupportedExtensions( h.getExtensionOids() );
        }

        try
        {
            // Disable the disconnection of the clients on unbind
            SocketAcceptorConfig acceptorCfg = new SocketAcceptorConfig();
            acceptorCfg.setDisconnectOnUnbind( false );
            acceptorCfg.setReuseAddress( true );
            acceptorCfg.setFilterChainBuilder( chainBuilder );
            acceptorCfg.setThreadModel( threadModel );
            
            ((SocketSessionConfig)(acceptorCfg.getSessionConfig())).setTcpNoDelay( true );
            
            tcpAcceptor.bind( new InetSocketAddress( port ), protocolProvider.getHandler(), acceptorCfg );
            ldapStarted = true;
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Successful bind of an LDAP Service (" + port + ") is complete." );
            }
        }
        catch ( IOException e )
        {
            String msg = "Failed to bind an LDAP service (" + port + ") to the service registry.";
            LdapConfigurationException lce = new LdapConfigurationException( msg );
            lce.setRootCause( e );
            log.error( msg, e );
            throw lce;
        }
    }


    private void startKerberos( ServerStartupConfiguration cfg, Hashtable env )
    {
        if ( cfg.isEnableKerberos() )
        {
            try
            {
                KdcConfiguration kdcConfiguration = new KdcConfiguration( env, LoadStrategy.PROPS );
                PrincipalStore kdcStore = new JndiPrincipalStoreImpl( kdcConfiguration, this );
                
                DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig();
                udpConfig.setThreadModel( threadModel );

                SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig();
                tcpConfig.setDisconnectOnUnbind( false );
                tcpConfig.setReuseAddress( true );
                tcpConfig.setFilterChainBuilder( new DefaultIoFilterChainBuilder() );
                tcpConfig.setThreadModel( threadModel );

                tcpKdcServer = new KerberosServer( kdcConfiguration, tcpAcceptor, tcpConfig, kdcStore );
                udpKdcServer = new KerberosServer( kdcConfiguration, udpAcceptor, udpConfig, kdcStore );
            }
            catch ( Throwable t )
            {
                log.error( "Failed to start the Kerberos service", t );
            }
        }
    }


    private void startChangePassword( ServerStartupConfiguration cfg, Hashtable env )
    {
        if ( cfg.isEnableChangePassword() )
        {
            try
            {
                ChangePasswordConfiguration changePasswordConfiguration = new ChangePasswordConfiguration( env,
                    LoadStrategy.PROPS );
                PrincipalStore store = new JndiPrincipalStoreImpl( changePasswordConfiguration, this );

                DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig();
                udpConfig.setThreadModel( threadModel );

                SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig();
                tcpConfig.setDisconnectOnUnbind( false );
                tcpConfig.setReuseAddress( true );
                tcpConfig.setFilterChainBuilder( new DefaultIoFilterChainBuilder() );
                tcpConfig.setThreadModel( threadModel );

                tcpChangePasswordServer = new ChangePasswordServer( changePasswordConfiguration, tcpAcceptor, 
                    tcpConfig, store );
                udpChangePasswordServer = new ChangePasswordServer( changePasswordConfiguration, udpAcceptor, 
                    udpConfig, store );
            }
            catch ( Throwable t )
            {
                log.error( "Failed to start the Change Password service", t );
            }
        }
    }


    private void startNTP( ServerStartupConfiguration cfg, Hashtable env )
    {
        if ( cfg.isEnableNtp() )
        {
            try
            {
                NtpConfiguration ntpConfig = new NtpConfiguration( env, LoadStrategy.PROPS );

                DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig();
                udpConfig.setThreadModel( threadModel );

                SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig();
                tcpConfig.setDisconnectOnUnbind( false );
                tcpConfig.setReuseAddress( true );
                tcpConfig.setFilterChainBuilder( new DefaultIoFilterChainBuilder() );
                tcpConfig.setThreadModel( threadModel );

                tcpNtpServer = new NtpServer( ntpConfig, tcpAcceptor, tcpConfig );
                udpNtpServer = new NtpServer( ntpConfig, udpAcceptor, udpConfig );
            }
            catch ( Throwable t )
            {
                log.error( "Failed to start the NTP service", t );
            }
        }
    }


    private void stopLDAP0( int port )
    {
        try
        {
            // we should unbind the service before we begin sending the notice 
            // of disconnect so new connections are not formed while we process
            List writeFutures = new ArrayList();

            // If the socket has already been unbound as with a successful 
            // GracefulShutdownRequest then this will complain that the service
            // is not bound - this is ok because the GracefulShutdown has already
            // sent notices to to the existing active sessions
            List sessions = null;
        
            try
            {
                sessions = new ArrayList( tcpAcceptor.getManagedSessions( new InetSocketAddress( port ) ) );
            }
            catch ( IllegalArgumentException e )
            {
                log.warn( "Seems like the LDAP service (" + port + ") has already been unbound." );
                return;
            }

            tcpAcceptor.unbind( new InetSocketAddress( port ) );
            
            if ( log.isInfoEnabled() )
            {
                log.info( "Unbind of an LDAP service (" + port + ") is complete." );
                log.info( "Sending notice of disconnect to existing clients sessions." );
            }

            // Send Notification of Disconnection messages to all connected clients.
            if ( sessions != null )
            {
                for ( Iterator i = sessions.iterator(); i.hasNext(); )
                {
                    IoSession session = ( IoSession ) i.next();
                    writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) );
                }
            }

            // And close the connections when the NoDs are sent.
            Iterator sessionIt = sessions.iterator();
            
            for ( Iterator i = writeFutures.iterator(); i.hasNext(); )
            {
                WriteFuture future = ( WriteFuture ) i.next();
                future.join( 1000 );
                ( ( IoSession ) sessionIt.next() ).close();
            }
        }
        catch ( Exception e )
        {
            log.warn( "Failed to sent NoD.", e );
        }
    }
}
