package com.ati.teste;

import java.util.logging.Logger;

import org.apache.directory.server.core.entry.ClonedServerEntry;
import org.apache.directory.server.core.filtering.BaseEntryFilteringCursor;
import org.apache.directory.server.core.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.interceptor.context.BindOperationContext;
import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
import org.apache.directory.server.core.interceptor.context.ListOperationContext;
import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.shared.ldap.cursor.EmptyCursor;
import org.apache.directory.shared.ldap.cursor.SingletonCursor;
import org.apache.directory.shared.ldap.entry.DefaultServerEntry;
import org.apache.directory.shared.ldap.entry.ServerEntry;
import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.schema.SchemaManager;

public class HelloWorldPartition implements Partition {

	private static final Logger LOG = Logger
			.getLogger(HelloWorldPartition.class.getName());
	private String id;
    private String suffix;
    private DN normSuffixDN;
	private ServerEntry entryEricsson;
	private SchemaManager schemaManager;
	private DN dn;

	public HelloWorldPartition(String id, String suffix) {
		this.id = id;
		this.suffix = suffix;
	}

	public void add(AddOperationContext arg0) throws Exception {
		LOG.info("add");
		// Não faz nada
	}

	public void delete(DeleteOperationContext arg0) throws Exception {
		LOG.info("delete");
		// Não faz nada
	}

	public void modify(ModifyOperationContext arg0) throws Exception {
		LOG.info("modify");
		// Não faz nada
	}

	public void move(MoveOperationContext arg0) throws Exception {
		LOG.info("move");
		// Não faz nada
	}

	public void moveAndRename(MoveAndRenameOperationContext arg0)
			throws Exception {
		LOG.info("move and rename");
		// Não faz nada
	}

	public void rename(RenameOperationContext arg0) throws Exception {
		LOG.info("rename");
		// Não faz nada
	}

	public void bind(BindOperationContext arg0) throws Exception {
		LOG.info("bind");
		// Não faz nada
	}

	public void sync() throws Exception {
		LOG.info("sync");
		// Não faz nada
	}

	public void unbind(UnbindOperationContext arg0) throws Exception {
		LOG.info("ubind");
		// Não faz nada
	}

	public void destroy() throws Exception {
		LOG.info("destroy");
	}

	public String getId() {
		LOG.info("get id");
		return id;
	}

	public String getSuffix() {
		LOG.info("get suffix");
		return suffix;
	}

	public DN getSuffixDn() {
		LOG.info("get suffix dn");
		return normSuffixDN;
	}
	
    public DN getUpSuffixDn() throws Exception
    {
        return new DN(suffix);
    }	

	public void initialize() throws Exception {
		String infoMsg = String.format("Initializing %s with suffix %s", this
				.getClass().getSimpleName(), this.suffix);
	    setSuffix(this.suffix);
		LOG.info(infoMsg);
		entryEricsson = new DefaultServerEntry(getSchemaManager(), getSuffixDn());
		entryEricsson.add("objectClass", "top", "dcObject", "organization");
		entryEricsson.add("dc", "ericsson");
		entryEricsson.add("o", "Sony Ericsson");
		LOG.info("Initializing done.");
	}

	public boolean isInitialized() {
		LOG.info("Is initialized");
		return this.entryEricsson != null;
	}

	public void setId(String arg0) {
		LOG.info("set id");
		id = arg0;
	}

	/**
	 * Verifica o se existe uma entrada no LDAP.
	 */
	public boolean hasEntry(EntryOperationContext entry) throws Exception {
		LOG.info("hasEntry");
		return entry.getDn().equals(dn);
	}

	public SchemaManager getSchemaManager() {
		LOG.info("getSchemaManager");
		return schemaManager;
	}

	public EntryFilteringCursor list(ListOperationContext arg0)
			throws Exception {
		LOG.info("list");
		return null;
	}

	public ClonedServerEntry lookup(LookupOperationContext lookupContext)
			throws Exception {
		LOG.info("lookup");
		return null;
	}

	public EntryFilteringCursor search(SearchOperationContext ctx)
			throws Exception {
		LOG.info("search!!!!!");
		LOG.info("search((dn=" + ctx.getDn() + ", filter=" + ctx.getFilter()
				+ ", scope=" + ctx.getScope() + ")");
		if (ctx.getDn().equals(this.dn)) {
			switch (ctx.getScope()) {
			case OBJECT:
				// return a result with the only entry we have
				return new BaseEntryFilteringCursor(
						new SingletonCursor<ServerEntry>(this.entryEricsson),
						ctx);
			}
		}

		// return an empty result
		return new BaseEntryFilteringCursor(new EmptyCursor<ServerEntry>(), ctx);
	}

	public void setSchemaManager(SchemaManager arg0) {
		LOG.info("set schema manager");
		this.schemaManager = arg0;
	}

	public void setSuffix(String suffix) throws LdapInvalidDnException {
		LOG.info("set suffix");
		if (!suffix.startsWith("ou=")) {
			throw new IllegalArgumentException("suffix has to start with ou");
		}
		this.suffix = suffix;
		
        try
        {
            this.normSuffixDN= DN.normalize( new DN(suffix), getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
        }
        catch ( Exception e )
        {
            throw new RuntimeException();
        }		
	}

}