/*
 *  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.configuration;


import org.apache.commons.lang.StringUtils;
import org.apache.directory.server.constants.ApacheSchemaConstants;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.DefaultDirectoryService;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.authn.LdapPrincipal;
import org.apache.directory.server.ldap.LdapServer;
import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
import org.apache.directory.server.protocol.shared.store.LdifLoadFilter;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.util.StringTools;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.SimpleByteBufferAllocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * Apache Directory Server top level.
 *
 * @org.apache.xbean.XBean
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class ApacheDS
{
    private static final Logger LOG = LoggerFactory.getLogger( ApacheDS.class.getName() );
    
    /** Default delay between two flushes to the backend */
    private static final long DEFAULT_SYNC_PERIOD_MILLIS = 20000;

    /** Wainting period between two flushes to the backend */
    private long synchPeriodMillis = DEFAULT_SYNC_PERIOD_MILLIS;

    /** Directory where are stored the LDIF files to be loaded at startup */
    private File ldifDirectory;
    
    private final List<LdifLoadFilter> ldifFilters = new ArrayList<LdifLoadFilter>();

    /** The LDAP server protocol handler */
    private final LdapServer ldapServer;
    
    /** The LDAPS server protocol handler */
    private final LdapServer ldapsServer;
    
    /** The directory service */
    private final DirectoryService directoryService;


    /**
     * Creates a new instance of the ApacheDS server
     *  
     * @param directoryService 
     * @param ldapServer
     * @param ldapsServer
     */
    public ApacheDS( DirectoryService directoryService, LdapServer ldapServer, LdapServer ldapsServer )
    {
        LOG.info(  "Starting the Apache Directory Server" );

        if ( directoryService == null )
        {
            this.directoryService = new DefaultDirectoryService();
        }
        else
        {        
            this.directoryService = directoryService;
        }
        
        this.ldapServer = ldapServer;
        this.ldapsServer = ldapsServer;
        ByteBuffer.setAllocator( new SimpleByteBufferAllocator() );
        ByteBuffer.setUseDirectBuffers( false );
    }


    /**
     * Start the server :
     *  <li>initialize the DirectoryService</li>
     *  <li>start the LDAP server</li>
     *  <li>start the LDAPS server</li>
     *  
     * @throws NamingException If the server cannot be started
     * @throws IOException If an IO error occured while reading some file
     */
    public void startup() throws NamingException, IOException
    {
        LOG.debug( "Starting the server" );
        
        // Start the directory service if not started yet
        if ( ! directoryService.isStarted() )
        {
            LOG.debug( "1. Starting the DirectoryService" );
            directoryService.startup();
        }

        // Load the LDIF files - if any - into the server
        loadLdifs();

        // Start the LDAP server
        if ( ldapServer != null && ! ldapServer.isStarted() )
        {
            LOG.debug( "3. Starting the LDAP server" );
            ldapServer.start();
        }

        // Start the LDAPS  server
        if ( ldapsServer != null && ! ldapsServer.isStarted() )
        {
            LOG.debug(  "4. Starting the LDAPS server" );
            ldapsServer.start();
        }
        
        LOG.debug( "Server successfully started" );
    }


    public boolean isStarted()
    {
        if ( ldapServer != null || ldapsServer != null )
        {
             return ( ldapServer != null && ldapServer.isStarted() )
                     || ( ldapsServer != null && ldapsServer.isStarted() );
        }
        
        return directoryService.isStarted();
    }
    

    public void shutdown() throws NamingException
    {
        if ( ldapServer != null && ldapServer.isStarted() )
        {
            ldapServer.stop();
        }

        if ( ldapsServer != null && ldapsServer.isStarted() )
        {
            ldapsServer.stop();
        }

        directoryService.shutdown();
    }


    public LdapServer getLdapServer()
    {
        return ldapServer;
    }


    public LdapServer getLdapsServer()
    {
        return ldapsServer;
    }


    public DirectoryService getDirectoryService()
    {
        return directoryService;
    }


    public long getSynchPeriodMillis()
    {
        return synchPeriodMillis;
    }


    public void setSynchPeriodMillis( long synchPeriodMillis )
    {
        LOG.info( "Set the synchPeriodMillis to {}", synchPeriodMillis );
        this.synchPeriodMillis = synchPeriodMillis;
    }

    
    /**
     * Get the directory where 
     * @return
     */
    public File getLdifDirectory()
    {
        return ldifDirectory;
    }


    public void setAllowAnonymousAccess( boolean allowAnonymousAccess )
    {
        LOG.info( "Set the allowAnonymousAccess flag to {}", allowAnonymousAccess );
        
        directoryService.setAllowAnonymousAccess( allowAnonymousAccess );
        
        if ( ldapServer != null )
        {
            ldapServer.setAllowAnonymousAccess( allowAnonymousAccess );
        }
        
        if ( ldapsServer != null )
        {
            ldapsServer.setAllowAnonymousAccess( allowAnonymousAccess );
        }
    }


    public void setLdifDirectory( File ldifDirectory )
    {
        LOG.info( "The LDIF directory file is {}", ldifDirectory.getAbsolutePath() );
        this.ldifDirectory = ldifDirectory;
    }
    
    
    // ----------------------------------------------------------------------
    // From CoreContextFactory: presently in intermediate step but these
    // methods will be moved to the appropriate protocol service eventually.
    // This is here simply to start to remove the JNDI dependency then further
    // refactoring will be needed to place these where they belong.
    // ----------------------------------------------------------------------


    /**
     * Check that the entry where are stored the loaded Ldif files is created.
     * 
     * If not, create it.
     * 
     * The files are stored in ou=loadedLdifFiles,ou=configuration,ou=system
     */
    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( ServerDNConstants.LDIF_FILES_DN, entry );
            LOG.info( "Creating " + ServerDNConstants.LDIF_FILES_DN );
        }
        catch ( NamingException e )
        {
            LOG.info( ServerDNConstants.LDIF_FILES_DN + " exists" );
        }
    }


    /**
     * Create a string containing a hex dump of the loaded ldif file name.
     * 
     * It is associated with the attributeType wrt to the underlying system.
     */
    private String buildProtectedFileEntry( File ldif )
    {
        String fileSep = File.separatorChar == '\\' ? 
                ApacheSchemaConstants.WINDOWS_FILE_AT : 
                ApacheSchemaConstants.UNIX_FILE_AT;

        return  fileSep + 
                "=" + 
                StringTools.dumpHexPairs( StringTools.getBytesUtf8( getCanonical( ldif ) ) ) +
                "," + 
                ServerDNConstants.LDIF_FILES_DN; 
    }

    
    private void addFileEntry( DirContext root, File ldif ) throws NamingException
    {
        String rdnAttr = File.separatorChar == '\\' ? 
            ApacheSchemaConstants.WINDOWS_FILE_AT : 
            ApacheSchemaConstants.UNIX_FILE_AT;
        String oc = File.separatorChar == '\\' ? ApacheSchemaConstants.WINDOWS_FILE_OC : ApacheSchemaConstants.UNIX_FILE_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 );
    }


    /**
     * 
     * @param root
     * @param ldif
     * @return
     */
    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;

        try
        {
            canonical = file.getCanonicalPath();
        }
        catch ( IOException e )
        {
            LOG.error( "could not get canonical path", e );
            return null;
        }

        return StringUtils.replace( canonical, "\\", "\\\\" );
    }


    /**
     * Load a ldif into the directory.
     *  
     * @param root The context in which we will inject the entries
     * @param ldifFile The ldif file to read
     * @throws NamingException If something went wrong while loading the entries
     */
    private void loadLdif( DirContext root, File ldifFile ) throws NamingException
    {
        Attributes fileEntry = getLdifFileEntry( root, ldifFile );

        if ( fileEntry != null )
        {
            String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get();
            LOG.info( "Load of LDIF file '" + getCanonical( ldifFile )
                    + "' skipped.  It has already been loaded on " + time + "." );
        }
        else
        {
            LdifFileLoader loader = new LdifFileLoader( root, ldifFile, ldifFilters );
            int count = loader.execute();
            LOG.info( "Loaded " + count + " entries from LDIF file '" + getCanonical( ldifFile ) + "'" );
            addFileEntry( root, ldifFile );
        }
    }
    
    
    /**
     * Load the ldif files if there are some
     */
    public void loadLdifs() throws NamingException
    {
        // LOG and bail if property not set
        if ( ldifDirectory == 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 ( ! ldifDirectory.exists() )
        {
            LOG.warn( "LDIF load directory '{}' does not exist.  No LDIF files will be loaded.",
                getCanonical( ldifDirectory ) );
            return;
        }


        LdapDN dn = new LdapDN( ServerDNConstants.ADMIN_SYSTEM_DN );
        
        // Must normalize the dn or - IllegalStateException!
        AttributeTypeRegistry reg = directoryService.getRegistries().getAttributeTypeRegistry();
        dn.normalize( reg.getNormalizerMapping() );
        
        LdapPrincipal admin = new LdapPrincipal( dn, AuthenticationLevel.STRONG );
        
        
        DirContext root = directoryService.getJndiContext( admin );
        ensureLdifFileBase( root );

        // if ldif directory is a file try to load it
        if ( ldifDirectory.isFile() )
        {
            if ( LOG.isInfoEnabled() )
            {
                LOG.info( "LDIF load directory '{}' is a file. Will attempt to load as LDIF.",
                    getCanonical( ldifDirectory ) );
            }

            try
            {
                loadLdif( root, ldifDirectory );
            }
            catch ( NamingException ne )
            {
                // If the file can't be read, log the error, and stop
                // loading LDIFs.
                LOG.error( "Cannot load the ldif file '{}', error : ",
                    ldifDirectory.getAbsolutePath(), 
                    ne.getMessage() );
                throw ne;
            }
        }
        else
        {
            // get all the ldif files within the directory (should be sorted alphabetically)
            File[] ldifFiles = ldifDirectory.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 '{}' does not contain any LDIF files. No LDIF files will be loaded.", 
                    getCanonical( ldifDirectory ) );
                return;
            }
    
            // load all the ldif files and load each one that is loaded
            for ( File ldifFile : ldifFiles )
            {
                try
                {
                    LOG.info(  "Loading LDIF file '{}'", ldifFile.getName() );
                    loadLdif( root, ldifFile );
                }
                catch ( NamingException ne )
                {
                    // If the file can't be read, log the error, and stop
                    // loading LDIFs.
                    LOG.error( "Cannot load the ldif file '{}', error : {}", 
                        ldifFile.getAbsolutePath(), 
                        ne.getMessage() );
                    throw ne;
                }
            }
        }
    }
}
