package com.polycom.rm.ds;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import org.apache.directory.server.core.DefaultDirectoryService;
import org.apache.directory.server.core.entry.DefaultServerEntry;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.ldap.LdapServer;
import org.apache.directory.server.ldap.support.extended.StartTlsHandler;
import org.apache.directory.server.protocol.shared.SocketAcceptor;
import org.apache.directory.server.schema.SerializableComparator;
import org.apache.directory.server.schema.bootstrap.ApacheSchema;
import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
import org.apache.directory.server.schema.bootstrap.CoreSchema;
import org.apache.directory.server.schema.bootstrap.Schema;
import org.apache.directory.server.schema.bootstrap.SystemSchema;
import org.apache.directory.server.schema.registries.DefaultOidRegistry;
import org.apache.directory.server.schema.registries.DefaultRegistries;
import org.apache.directory.server.schema.registries.OidRegistry;
import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.jboss.system.ServiceMBeanSupport;


public class DsService extends ServiceMBeanSupport implements DsServiceMBean
{
   // paths are relative from jboss/bin/
   private static final String LDIF_DIR = "../ads-ldif";
   private static final String WORK_DIR = "../ads-work";
   private static final int ADS_PORT = 389;
   private LdapServer apacheds;
   
   @Override
   protected void startService()
      throws Exception
   {
      log.info("------------- DsService::startService");
      startApacheDS();
   }
   
   @Override
   protected void stopService()
      throws Exception
   {
      log.info("-------------- DsService::stopService");
      stopApacheDS();
   }

   private void startApacheDS()
      throws Exception
   {
      log.info("------------- DsService::startApacheDS");
      try
      {
          log.info("ldif directory ["+new File(LDIF_DIR).getAbsoluteFile()+"]");

          BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
          OidRegistry oidRegistry = new DefaultOidRegistry();
          Registries registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
          SerializableComparator.setRegistry( registries.getComparatorRegistry() );

          // load essential bootstrap schemas
          Set<Schema> bootstrapSchemas = new HashSet<Schema>();
          bootstrapSchemas.add( new ApachemetaSchema() );
          bootstrapSchemas.add( new ApacheSchema() );
          bootstrapSchemas.add( new CoreSchema() );
          bootstrapSchemas.add( new SystemSchema() );
          loader.loadWithDependencies( bootstrapSchemas, registries );
          
          JdbcPartition partition = new JdbcPartition();
          partition.setId("ReadiManager Partition");
          partition.setSuffix("ou=ReadiManager");
          
          ServerEntry contextEntry = new DefaultServerEntry( registries, new LdapDN( "ou=ReadiManager" ) );
          contextEntry.add( "objectClass", "top", "organizationalUnit"); //, "extensibleObject" );
          contextEntry.add( "ou", "ReadiManager");
          partition.setContextEntry( contextEntry );
          
          
          DefaultDirectoryService directoryService = new DefaultDirectoryService();
          directoryService.setWorkingDirectory( new File( WORK_DIR ).getAbsoluteFile() );
          directoryService.setShutdownHookEnabled( false );
          directoryService.startup();
          directoryService.addPartition(partition);
          
          SocketAcceptor socketAcceptor = new SocketAcceptor( null );
          LdapServer ldapServer = new LdapServer();
          ldapServer.setSocketAcceptor( socketAcceptor );
          ldapServer.setDirectoryService( directoryService );
          ldapServer.setIpPort( ADS_PORT );

          ldapServer.addExtendedOperationHandler( new StartTlsHandler() );
          ldapServer.start();
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);
      }
   }

   private void stopApacheDS()
      throws Exception
   {
      log.info("-------------- DsService::stopApacheDS");
      apacheds.stop();
   }
}
