package org.apache.archiva.redback.components.apacheds;

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

import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
import org.apache.directory.server.core.configuration.ShutdownConfiguration;
import org.apache.directory.server.core.configuration.SyncConfiguration;
import org.apache.directory.server.jndi.ServerContextFactory;
import org.apache.directory.server.ldap.LdapConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.Context;
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.InitialDirContext;
import java.io.File;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;

/**
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 * @author Olivier Lamy
 *
 */
public class DefaultApacheDs
    implements ApacheDs
{

    private Logger logger = LoggerFactory.getLogger( getClass() );

    // ----------------------------------------------------------------------
    // Configuration
    // ----------------------------------------------------------------------

    private boolean enableNetworking;

    private File basedir;

    private int port;

    private String password;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private boolean stopped;

    private MutableServerStartupConfiguration configuration;

    private Set partitionConfigurations = new HashSet();

    // ----------------------------------------------------------------------
    // ApacheDs Implementation
    // ----------------------------------------------------------------------

    public void setBasedir( File basedir )
    {
        this.basedir = basedir;
    }

    public void setEnableNetworking( boolean enableNetworking )
    {
        this.enableNetworking = enableNetworking;
    }

    public InitialDirContext getAdminContext()
        throws NamingException
    {
        assertIsStarted();

        Hashtable environment = new Hashtable( configuration.toJndiEnvironment() );
        environment.put( Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName() );
        environment.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
        environment.put( Context.SECURITY_CREDENTIALS, password );
        environment.put( Context.SECURITY_AUTHENTICATION, "simple" );
//        environment.put( Context.PROVIDER_URL, "dc=hauskeeper,dc=codehaus,dc=org" );
        return new InitialDirContext( environment );
    }

    public InitialDirContext getSystemContext()
        throws NamingException
    {
        assertIsStarted();

        Hashtable environment = new Hashtable( configuration.toJndiEnvironment() );
        environment.put( Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName() );
        environment.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
        environment.put( Context.SECURITY_CREDENTIALS, password );
        environment.put( Context.SECURITY_AUTHENTICATION, "simple" );
        environment.put( Context.PROVIDER_URL, "ou=system" );
        return new InitialDirContext( environment );
    }

    public void addPartition( String name, String root, Set indexedAttributes, Attributes partitionAttributes )
        throws NamingException
    {
        MutablePartitionConfiguration configuration = new MutablePartitionConfiguration();
        configuration.setId( name );
        configuration.setSuffix( root );
        configuration.setIndexedAttributes( indexedAttributes );
        configuration.setContextEntry( partitionAttributes );
        partitionConfigurations.add( configuration );
    }

    public void addPartition( Partition partition )
        throws NamingException
    {
        MutablePartitionConfiguration configuration = new MutablePartitionConfiguration();

        configuration.setId( partition.getName() );
        configuration.setSuffix( partition.getSuffix() );
        configuration.setIndexedAttributes( partition.getIndexedAttributes() );
        configuration.setContextEntry( partition.getContextAttributes() );
        //configuration.setSynchOnWrite( true );
        configuration.setCacheSize( 1 );
        //configuration.setOptimizerEnabled( false );
        partitionConfigurations.add( configuration );
    }

    public Partition addSimplePartition( String name, String[] domainComponents )
        throws NamingException
    {
        if ( domainComponents.length == 0 )
        {
            throw new NamingException( "Illegal argument, there has to be at least one domain component." );
        }

        StringBuilder suffix = new StringBuilder();

        for ( int i = 0; i < domainComponents.length; i++ )
        {
            String dc = domainComponents[i];

            suffix.append( "dc=" ).append( dc );

            if ( i != domainComponents.length - 1 )
            {
                suffix.append( "," );
            }
        }

        // ----------------------------------------------------------------------
        // The root entry of the partition
        // ----------------------------------------------------------------------

        Attributes attributes = new BasicAttributes( true );
        attributes.put( "dc", domainComponents[0] );
        Attribute objectClass = new BasicAttribute( "objectClass" );
        objectClass.add( "top" );
        objectClass.add( "domain" );
        objectClass.add( "extensibleObject" );
        attributes.put( objectClass );

        Partition partition = new Partition();
        partition.setName( name );
        partition.setSuffix( suffix.toString() );
        partition.setContextAttributes( attributes );
        HashSet set = new HashSet();
        set.add( "uid" );
        set.add( "cn" );
        partition.setIndexedAttributes( set );

        addPartition( partition );

        return partition;
    }

    public void startServer()
        throws Exception
    {
        logger.info( "Starting Apache Directory Server server." );

        logger.info( "ApacheDS basedir: " + basedir.getAbsolutePath() );

        File logs = new File( basedir, "logs" );

        if ( !logs.exists() && !logs.mkdirs() )
        {
            throw new Exception( "Could not create logs directory: " + logs.getAbsolutePath() );
        }

        Properties environment = new Properties();
        environment.setProperty( "java.naming.security.authentication", "simple" );
        environment.setProperty( "java.naming.security.principal", "uid=admin,ou=system" );
        if ( password != null )
        {
            environment.setProperty( "java.naming.security.credentials", password );
        }
        MutableServerStartupConfiguration configuration = new MutableServerStartupConfiguration();
        configuration.setWorkingDirectory( basedir );
        configuration.setAllowAnonymousAccess( true );
        //configuration.setEnableNtp( false );
        //configuration.setEnableKerberos( false );
        //configuration.setEnableChangePassword( false );
        LdapConfiguration config = new LdapConfiguration();
        config.setIpPort( port );
        configuration.setLdapConfiguration( config );
        configuration.setEnableNetworking( enableNetworking );
        configuration.setSynchPeriodMillis( 100 );

        if ( configuration.getPartitionConfigurations() == null || ( configuration.getPartitionConfigurations() != null
            && configuration.getPartitionConfigurations().isEmpty() ) )
        {
            configuration.setPartitionConfigurations( partitionConfigurations );
        }
        Properties env = new Properties();
        env.setProperty( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
        if ( password != null )
        {
            env.setProperty( Context.SECURITY_CREDENTIALS, password );
        }
        env.setProperty( Context.SECURITY_AUTHENTICATION, "simple" );
        env.setProperty( Context.PROVIDER_URL, "ou=system" );
        env.setProperty( Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName() );
        env.putAll( configuration.toJndiEnvironment() );
        InitialDirContext context = new InitialDirContext( env );

        //Attributes inetAttributes = context.getAttributes( "cn=inetorgperson,ou=schema" );

        //inetAttributes.remove( "m-disabled" );

        this.configuration = configuration;

        logger.info( "Started Apache Directory Server server." );

        stopped = false;
    }

    public void stopServer()
        throws Exception
    {
        if ( stopped )
        {
            throw new Exception( "Already stopped." );
        }

        logger.info( "Stopping Apache Directory Server server." );

        sync();

        stopped = true;

        Hashtable env = new Hashtable();
        env.putAll( new ShutdownConfiguration().toJndiEnvironment() );
        new InitialDirContext( env );

        logger.info( "Apache Directory Server server stopped." );
    }

    public boolean isStopped()
    {
        return stopped;
    }

    public void sync()
        throws Exception
    {
        logger.info( "Sync'ing Apache Directory Server server." );

        Hashtable env = new Hashtable();
        env.putAll( new SyncConfiguration().toJndiEnvironment() );
        new InitialDirContext( env );
    }


    public void stop()
    {
        try
        {
            if ( !stopped )
            {
                stopServer();
            }
        }
        catch ( Exception e )
        {
            throw new RuntimeException( "Error while stopping Apache Directory Server server.", e );
        }
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private void assertIsStarted()
        throws NamingException
    {
        if ( configuration == null )
        {
            throw new NamingException( "The server has to be started before used." );
        }
    }

    public int getPort()
    {
        return port;
    }

    public void setPort( int port )
    {
        this.port = port;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword( String password )
    {
        this.password = password;
    }
}
