/*
 *
 *   Licensed 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.ldap.support;


import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.event.NamespaceChangeListener;
import javax.naming.event.NamingEvent;
import javax.naming.event.NamingExceptionEvent;
import javax.naming.event.ObjectChangeListener;

import org.apache.directory.server.core.jndi.ServerLdapContext;
import org.apache.directory.server.ldap.SessionRegistry;
import org.apache.directory.shared.ldap.codec.search.controls.ChangeType;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.exception.OperationAbandonedException;
import org.apache.directory.shared.ldap.message.AbandonListener;
import org.apache.directory.shared.ldap.message.AbandonableRequest;
import org.apache.directory.shared.ldap.message.EntryChangeControl;
import org.apache.directory.shared.ldap.message.LdapResult;
import org.apache.directory.shared.ldap.message.PersistentSearchControl;
import org.apache.directory.shared.ldap.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.message.SearchRequest;
import org.apache.directory.shared.ldap.message.SearchResponseEntry;
import org.apache.directory.shared.ldap.message.SearchResponseEntryImpl;
import org.apache.directory.shared.ldap.util.ExceptionUtils;
import org.apache.mina.common.IoSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A JNDI NamingListener implementation which sends back added, deleted, modified or 
 * renamed entries to a client that created this listener.  This class is part of the
 * persistent search implementation which uses the event notification scheme built into
 * the server core.  This is exposed by the server side ApacheDS JNDI LDAP provider.
 * 
 * This listener is disabled only when a session closes or when an abandon request 
 * cancels it.  Hence time and size limits in normal search operations do not apply
 * here.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
class PersistentSearchListener implements ObjectChangeListener, NamespaceChangeListener, AbandonListener
{
    private static final Logger log = LoggerFactory.getLogger( SearchHandler.class );
    final ServerLdapContext ctx;
    final IoSession session;
    final SearchRequest req;
    final PersistentSearchControl control;


    PersistentSearchListener(ServerLdapContext ctx, IoSession session, SearchRequest req)
    {
        this.session = session;
        this.req = req;
        req.addAbandonListener( this );
        this.ctx = ctx;
        this.control = ( PersistentSearchControl ) req.getControls().get( PersistentSearchControl.CONTROL_OID );
    }


    public void abandon() throws NamingException
    {
        // must abandon the operation 
        ctx.removeNamingListener( this );

        /*
         * From RFC 2251 Section 4.11:
         * 
         * In the event that a server receives an Abandon Request on a Search  
         * operation in the midst of transmitting responses to the Search, that
         * server MUST cease transmitting entry responses to the abandoned
         * request immediately, and MUST NOT send the SearchResultDone. Of
         * course, the server MUST ensure that only properly encoded LDAPMessage
         * PDUs are transmitted. 
         * 
         * SO DON'T SEND BACK ANYTHING!!!!!
         */
    }


    public void namingExceptionThrown( NamingExceptionEvent evt )
    {
        // must abandon the operation and send response done with an
        // error message if this occurs because something is wrong

        try
        {
            ctx.removeNamingListener( this );
        }
        catch ( NamingException e )
        {
            log.error( "Attempt to remove listener from context failed", e );
        }

        /*
         * From RFC 2251 Section 4.11:
         * 
         * In the event that a server receives an Abandon Request on a Search  
         * operation in the midst of transmitting responses to the Search, that
         * server MUST cease transmitting entry responses to the abandoned
         * request immediately, and MUST NOT send the SearchResultDone. Of
         * course, the server MUST ensure that only properly encoded LDAPMessage
         * PDUs are transmitted. 
         * 
         * SO DON'T SEND BACK ANYTHING!!!!!
         */
        if ( evt.getException() instanceof OperationAbandonedException )
        {
            return;
        }

        SessionRegistry.getSingleton().removeOutstandingRequest( session, new Integer( req.getMessageId() ) );
        String msg = "failed on persistent search operation";

        if ( log.isDebugEnabled() )
        {
            msg += ":\n" + req + ":\n" + ExceptionUtils.getStackTrace( evt.getException() );
        }

        ResultCodeEnum code = null;
        if ( evt.getException() instanceof LdapException )
        {
            code = ( ( LdapException ) evt.getException() ).getResultCode();
        }
        else
        {
            code = ResultCodeEnum.getBestEstimate( evt.getException(), req.getType() );
        }

        LdapResult result = req.getResultResponse().getLdapResult();
        result.setResultCode( code );
        result.setErrorMessage( msg );
        if ( ( evt.getException().getResolvedName() != null )
            && ( ( code == ResultCodeEnum.NOSUCHOBJECT ) || ( code == ResultCodeEnum.ALIASPROBLEM )
                || ( code == ResultCodeEnum.INVALIDDNSYNTAX ) || ( code == ResultCodeEnum.ALIASDEREFERENCINGPROBLEM ) ) )
        {
            result.setMatchedDn( evt.getException().getResolvedName().toString() );
        }
        session.write( req.getResultResponse() );
    }


    public void objectChanged( NamingEvent evt )
    {
        // send the entry back
        sendEntry( evt );
    }


    public void objectAdded( NamingEvent evt )
    {
        // send the entry back
        sendEntry( evt );
    }


    public void objectRemoved( NamingEvent evt )
    {
        // send the entry back
        sendEntry( evt );
    }


    public void objectRenamed( NamingEvent evt )
    {
        // send the entry back
        sendEntry( evt );
    }


    private void sendEntry( NamingEvent evt )
    {
        /*
         * @todo eventually you'll want to add the changeNumber once we move 
         * the CSN functionality into the server.
         */
        SearchResponseEntry respEntry = new SearchResponseEntryImpl( req.getMessageId() );
        EntryChangeControl ecControl = null;

        if ( control.isReturnECs() )
        {
            ecControl = new EntryChangeControl();
            respEntry.add( ecControl );
        }

        switch ( evt.getType() )
        {
            case ( NamingEvent.OBJECT_ADDED  ):
                if ( !control.isNotificationEnabled( ChangeType.ADD ) )
                    return;
                respEntry.setObjectName( evt.getNewBinding().getName() );
                respEntry.setAttributes( ( Attributes ) evt.getChangeInfo() );
                if ( ecControl != null )
                {
                    ecControl.setChangeType( ChangeType.ADD );
                }
                break;
            case ( NamingEvent.OBJECT_CHANGED  ):
                if ( !control.isNotificationEnabled( ChangeType.MODIFY ) )
                    return;
                respEntry.setObjectName( evt.getOldBinding().getName() );
                respEntry.setAttributes( ( Attributes ) evt.getOldBinding().getObject() );
                if ( ecControl != null )
                {
                    ecControl.setChangeType( ChangeType.MODIFY );
                }
                break;
            case ( NamingEvent.OBJECT_REMOVED  ):
                if ( !control.isNotificationEnabled( ChangeType.DELETE ) )
                    return;
                respEntry.setObjectName( evt.getOldBinding().getName() );
                respEntry.setAttributes( ( Attributes ) evt.getOldBinding().getObject() );
                if ( ecControl != null )
                {
                    ecControl.setChangeType( ChangeType.DELETE );
                }
                break;
            case ( NamingEvent.OBJECT_RENAMED  ):
                if ( !control.isNotificationEnabled( ChangeType.MODDN ) )
                    return;
                respEntry.setObjectName( evt.getNewBinding().getName() );
                respEntry.setAttributes( ( Attributes ) evt.getNewBinding().getObject() );
                if ( ecControl != null )
                {
                    ecControl.setChangeType( ChangeType.MODDN );
                    ecControl.setPreviousDn( evt.getOldBinding().getName() );
                }
                break;
            default:
                return;
        }

        session.write( respEntry );
    }


    public void requestAbandoned( AbandonableRequest req )
    {
        try
        {
            abandon();
        }
        catch ( NamingException e )
        {
            log.error( "failed to properly abandon this persistent search", e );
        }
    }
}