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


import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.naming.directory.SearchControls;

import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.StringValue;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapOperationException;
import org.apache.directory.api.ldap.model.filter.EqualityNode;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.util.tree.DnNode;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.ReferralManager;
import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
import org.apache.directory.server.core.api.partition.PartitionNexus;


/**
 * Implement a referral Manager, handling the requests from the LDAP protocol.
 * <br>
 * Referrals are stored in a tree, where leaves are the referrals. We are using
 * the very same structure than for the partition manager.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class ReferralManagerImpl implements ReferralManager
{
    /** The referrals tree */
    private DnNode<Entry> referrals;

    /** A lock to guarantee the manager consistency */
    private ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();

    /** A storage for the ObjectClass attributeType */
    private AttributeType OBJECT_CLASS_AT;


    /**
     *
     * Creates a new instance of ReferralManagerImpl.
     *
     * @param directoryService The directory service
     * @throws Exception If we can't initialize the manager
     */
    public ReferralManagerImpl( DirectoryService directoryService ) throws LdapException
    {
        lockWrite();

        try
        {
            referrals = new DnNode<Entry>();
            PartitionNexus nexus = directoryService.getPartitionNexus();
    
            Set<String> suffixes = nexus.listSuffixes();
            OBJECT_CLASS_AT = directoryService.getSchemaManager().getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
    
            init( directoryService, suffixes.toArray( new String[]
                {} ) );
        }
        finally
        {
            unlock();
        }
    }


    /**
     * Get a read-lock on the referralManager.
     * No read operation can be done on the referralManager if this
     * method is not called before.
     */
    public void lockRead()
    {
        mutex.readLock().lock();
    }


    /**
     * Get a write-lock on the referralManager.
     * No write operation can be done on the referralManager if this
     * method is not called before.
     */
    public void lockWrite()
    {
        mutex.writeLock().lock();
    }


    /**
     * Release the read-write lock on the referralManager.
     * This method must be called after having read or modified the
     * ReferralManager
     */
    public void unlock()
    {
        if ( mutex.isWriteLockedByCurrentThread() )
        {
            mutex.writeLock().unlock();
        }
        else
        {
            mutex.readLock().unlock();
        }
    }


    /**
     * {@inheritDoc}
     */
    // This will suppress PMD.EmptyCatchBlock warnings in this method
    @SuppressWarnings("PMD.EmptyCatchBlock")
    public void addReferral( Entry entry )
    {
        try
        {
            referrals.add( entry.getDn(), entry );
        }
        catch ( LdapException ne )
        {
            // Do nothing
        }
    }


    /**
     * {@inheritDoc}
     */
    public void init( DirectoryService directoryService, String... suffixes ) throws LdapException
    {
        ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
            new StringValue( SchemaConstants.REFERRAL_OC ) );

        // Lookup for each entry with the ObjectClass = Referral value
        SearchControls searchControl = new SearchControls();
        searchControl.setReturningObjFlag( false );
        searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );

        CoreSession adminSession = directoryService.getAdminSession();
        PartitionNexus nexus = directoryService.getPartitionNexus();

        for ( String suffix : suffixes )
        {
            // We will store each entry's Dn into the Referral tree
            Dn suffixDn = directoryService.getDnFactory().create( suffix );

            SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, suffixDn,
                referralFilter, searchControl );
            searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
            EntryFilteringCursor cursor = nexus.search( searchOperationContext );

            try
            {
                // Move to the first entry in the cursor
                cursor.beforeFirst();

                while ( cursor.next() )
                {
                    Entry entry = cursor.get();

                    // Lock the referralManager
                    lockWrite();

                    try
                    {
                        // Add it at the right place
                        addReferral( entry );
                    }
                    finally
                    { 
                        // Unlock the referralManager
                        unlock();
                    }
                }

                cursor.close();
            }
            catch ( Exception e )
            {
                throw new LdapOperationException( e.getMessage(), e );
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public void remove( DirectoryService directoryService, Dn suffix ) throws Exception
    {
        ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
            new StringValue( SchemaConstants.REFERRAL_OC ) );

        // Lookup for each entry with the ObjectClass = Referral value
        SearchControls searchControl = new SearchControls();
        searchControl.setReturningObjFlag( false );
        searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );

        CoreSession adminSession = directoryService.getAdminSession();
        PartitionNexus nexus = directoryService.getPartitionNexus();

        // We will store each entry's Dn into the Referral tree
        SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, suffix,
            referralFilter, searchControl );
        searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
        EntryFilteringCursor cursor = nexus.search( searchOperationContext );

        // Move to the first entry in the cursor
        cursor.beforeFirst();

        while ( cursor.next() )
        {
            Entry entry = cursor.get();

            // Add it at the right place
            removeReferral( entry );
        }
    }


    /**
     * {@inheritDoc}
     */
    public boolean hasParentReferral( Dn dn )
    {
        DnNode<Entry> referral = referrals.getNode( dn );

        return ( referral != null ) && referral.isLeaf();
    }


    /**
     * {@inheritDoc}
     */
    public Entry getParentReferral( Dn dn )
    {
        if ( !hasParentReferral( dn ) )
        {
            return null;
        }

        return referrals.getElement( dn );
    }


    /**
     * {@inheritDoc}
     */
    public boolean isReferral( Dn dn )
    {
        Entry parent = referrals.getElement( dn );

        if ( parent != null )
        {
            return dn.equals( parent.getDn() );
        }
        else
        {
            return false;
        }
    }


    /**
     * {@inheritDoc}
     */
    public void removeReferral( Entry entry ) throws LdapException
    {
        referrals.remove( entry.getDn() );
    }
}
