/*
 *   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.api.filtering;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.directory.api.ldap.model.constants.Loggers;
import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
import org.apache.directory.api.ldap.model.cursor.ClosureMonitor;
import org.apache.directory.api.ldap.model.cursor.Cursor;
import org.apache.directory.api.ldap.model.cursor.CursorException;
import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.OperationAbandonedException;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.server.core.api.entry.ClonedServerEntry;
import org.apache.directory.server.core.api.entry.ServerEntryUtils;
import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A Cursor which uses a list of filters to selectively return entries and/or
 * modify the contents of entries.  Uses lazy pre-fetching on positioning
 * operations which means adding filters after creation will not miss candidate
 * entries.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class EntryFilteringCursorImpl extends AbstractCursor<Entry> implements EntryFilteringCursor
{
    /** the logger used by this class */
    private static final Logger log = LoggerFactory.getLogger( EntryFilteringCursorImpl.class );

    /** A dedicated log for cursors */
    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );

    /** Speedup for logs */
    private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();

    /** the underlying wrapped search results Cursor */
    private final Cursor<Entry> wrapped;

    /** the parameters associated with the search operation */
    private final SearchOperationContext operationContext;

    /** The SchemaManager */
    private final SchemaManager schemaManager;

    /** the list of filters to be applied */
    private final List<EntryFilter> filters;

    /** the first accepted search result that is pre fetched */
    private Entry prefetched;


    // ------------------------------------------------------------------------
    // C O N S T R U C T O R S
    // ------------------------------------------------------------------------

    /**
     * Creates a new entry filtering Cursor over an existing Cursor using a
     * single filter initially: more can be added later after creation.
     * 
     * @param wrapped the underlying wrapped Cursor whose entries are filtered
     * @param searchControls the controls of search that created this Cursor
     * @param invocation the search operation invocation creating this Cursor
     * @param filter a single filter to be used
     */
    public EntryFilteringCursorImpl( Cursor<Entry> wrapped,
        SearchOperationContext operationContext, SchemaManager schemaManager, EntryFilter filter )
    {
        this( wrapped, operationContext, schemaManager, Collections.singletonList( filter ) );
    }


    /**
     * Creates a new entry filtering Cursor over an existing Cursor using a
     * no filter initially: more can be added later after creation.
     * 
     * @param wrapped the underlying wrapped Cursor whose entries are filtered
     * @param searchControls the controls of search that created this Cursor
     * @param invocation the search operation invocation creating this Cursor
     * @param filter a single filter to be used
     */
    public EntryFilteringCursorImpl( Cursor<Entry> wrapped, SearchOperationContext operationContext,
        SchemaManager schemaManager )
    {
        if ( IS_DEBUG )
        {
            LOG_CURSOR.debug( "Creating BaseEntryFilteringCursor {}", this );
        }

        this.wrapped = wrapped;
        this.operationContext = operationContext;
        this.filters = new ArrayList<EntryFilter>();
        this.schemaManager = schemaManager;
    }


    /**
     * Creates a new entry filtering Cursor over an existing Cursor using a
     * list of filters initially: more can be added later after creation.
     * 
     * @param wrapped the underlying wrapped Cursor whose entries are filtered
     * @param operationContext the operation context that created this Cursor
     * @param invocation the search operation invocation creating this Cursor
     * @param filters a list of filters to be used
     */
    public EntryFilteringCursorImpl( Cursor<Entry> wrapped,
        SearchOperationContext operationContext,
        SchemaManager schemaManager,
        List<EntryFilter> filters )
    {
        if ( IS_DEBUG )
        {
            LOG_CURSOR.debug( "Creating BaseEntryFilteringCursor {}", this );
        }

        this.wrapped = wrapped;
        this.operationContext = operationContext;
        this.filters = new ArrayList<EntryFilter>();
        this.filters.addAll( filters );
        this.schemaManager = schemaManager;
    }


    // ------------------------------------------------------------------------
    // Class Specific Methods
    // ------------------------------------------------------------------------

    /* (non-Javadoc)
     * @see org.apache.directory.server.core.filtering.EntryFilteringCursor#isAbandoned()
     */
    public boolean isAbandoned()
    {
        return operationContext.isAbandoned();
    }


    /* (non-Javadoc)
     * @see org.apache.directory.server.core.filtering.EntryFilteringCursor#setAbandoned(boolean)
     */
    public void setAbandoned( boolean abandoned )
    {
        operationContext.setAbandoned( abandoned );

        if ( abandoned )
        {
            log.info( "Cursor has been abandoned." );
        }
    }


    /* (non-Javadoc)
     * @see org.apache.directory.server.core.filtering.EntryFilteringCursor#addEntryFilter(org.apache.directory.server.core.filtering.EntryFilter)
     */
    public boolean addEntryFilter( EntryFilter filter )
    {
        return filters.add( filter );
    }


    /* (non-Javadoc)
     * @see org.apache.directory.server.core.filtering.EntryFilteringCursor#removeEntryFilter(org.apache.directory.server.core.filtering.EntryFilter)
     */
    public boolean removeEntryFilter( EntryFilter filter )
    {
        return filters.remove( filter );
    }


    /**
     * {@inheritDoc}
     */
    public List<EntryFilter> getEntryFilters()
    {
        return Collections.unmodifiableList( filters );
    }


    /**
     * {@inheritDoc}
     */
    public SearchOperationContext getOperationContext()
    {
        return operationContext;
    }


    // ------------------------------------------------------------------------
    // Cursor Interface Methods
    // ------------------------------------------------------------------------
    /**
     * {@inheritDoc}
     */
    public void after( Entry element ) throws LdapException, CursorException
    {
        throw new UnsupportedOperationException();
    }


    /**
     * {@inheritDoc}
     */
    public void afterLast() throws LdapException, CursorException
    {
        wrapped.afterLast();
        prefetched = null;
    }


    /**
     * {@inheritDoc}
     */
    public boolean available()
    {
        return prefetched != null;
    }


    /**
     * {@inheritDoc}
     */
    public void before( Entry element ) throws LdapException, CursorException
    {
        throw new UnsupportedOperationException();
    }


    /**
     * {@inheritDoc}
     */
    public void beforeFirst() throws LdapException, CursorException
    {
        wrapped.beforeFirst();
        prefetched = null;
    }


    /**
     * {@inheritDoc}
     */
    public void close()
    {
        if ( IS_DEBUG )
        {
            LOG_CURSOR.debug( "Closing BaseEntryFilteringCursor {}", this );
        }

        wrapped.close();
        prefetched = null;
    }


    /**
     * {@inheritDoc}
     */
    public void close( Exception reason )
    {
        if ( IS_DEBUG )
        {
            LOG_CURSOR.debug( "Closing BaseEntryFilteringCursor {}", this );
        }

        wrapped.close( reason );
        prefetched = null;
    }


    /**
     * {@inheritDoc}
     */
    public final void setClosureMonitor( ClosureMonitor monitor )
    {
        wrapped.setClosureMonitor( monitor );
    }


    /**
     * {@inheritDoc}
     */
    public boolean first() throws LdapException, CursorException
    {
        if ( operationContext.isAbandoned() )
        {
            log.info( "Cursor has been abandoned." );
            close();
            throw new OperationAbandonedException();
        }

        beforeFirst();

        return next();
    }


    /**
     * {@inheritDoc}
     */
    public Entry get() throws InvalidCursorPositionException
    {
        if ( available() )
        {
            return prefetched;
        }

        throw new InvalidCursorPositionException();
    }


    /**
     * {@inheritDoc}
     */
    public boolean isClosed()
    {
        return wrapped.isClosed();
    }


    /**
     * {@inheritDoc}
     */
    public boolean last() throws LdapException, CursorException
    {
        if ( operationContext.isAbandoned() )
        {
            log.info( "Cursor has been abandoned." );
            close();
            throw new OperationAbandonedException();
        }

        afterLast();

        return previous();
    }


    /**
     * {@inheritDoc}
     */
    public boolean next() throws LdapException, CursorException
    {
        if ( operationContext.isAbandoned() )
        {
            log.info( "Cursor has been abandoned." );
            close();
            throw new OperationAbandonedException();
        }

        Entry tempResult = null;

        outer: while ( wrapped.next() )
        {
            Entry tempEntry = wrapped.get();

            if ( tempEntry == null )
            {
                // no candidate
                continue;
            }

            if ( tempEntry instanceof ClonedServerEntry )
            {
                tempResult = tempEntry;
            }
            else
            {
                tempResult = new ClonedServerEntry( tempEntry );
            }

            /*
             * O P T I M I Z A T I O N
             * -----------------------
             * 
             * Don't want to waste cycles on enabling a loop for processing
             * filters if we have zero or one filter.
             */

            if ( filters.isEmpty() )
            {
                prefetched = tempResult;
                ServerEntryUtils.filterContents(
                    schemaManager,
                    operationContext, prefetched );

                return true;
            }

            if ( ( filters.size() == 1 ) && filters.get( 0 ).accept( operationContext, tempResult ) )
            {
                prefetched = tempResult;
                ServerEntryUtils.filterContents(
                    schemaManager,
                    operationContext, prefetched );

                return true;
            }

            /* E N D   O P T I M I Z A T I O N */
            for ( EntryFilter filter : filters )
            {
                // if a filter rejects then short and continue with outer loop
                if ( !filter.accept( operationContext, tempResult ) )
                {
                    continue outer;
                }
            }

            /*
             * Here the entry has been accepted by all filters.
             */
            prefetched = tempResult;

            return true;
        }

        prefetched = null;

        return false;
    }


    /**
     * {@inheritDoc}
     */
    public boolean previous() throws LdapException, CursorException
    {
        if ( operationContext.isAbandoned() )
        {
            log.info( "Cursor has been abandoned." );
            close();
            throw new OperationAbandonedException();
        }

        Entry tempResult = null;

        outer: while ( wrapped.previous() )
        {
            Entry entry = wrapped.get();

            if ( entry == null )
            {
                continue;
            }

            tempResult = new ClonedServerEntry/*Search*/( entry );

            /*
             * O P T I M I Z A T I O N
             * -----------------------
             * 
             * Don't want to waste cycles on enabling a loop for processing
             * filters if we have zero or one filter.
             */

            if ( filters.isEmpty() )
            {
                prefetched = tempResult;
                ServerEntryUtils.filterContents(
                    schemaManager,
                    operationContext, prefetched );

                return true;
            }

            if ( ( filters.size() == 1 ) && filters.get( 0 ).accept( operationContext, tempResult ) )
            {
                prefetched = tempResult;
                ServerEntryUtils.filterContents(
                    schemaManager,
                    operationContext, prefetched );

                return true;
            }

            /* E N D   O P T I M I Z A T I O N */

            for ( EntryFilter filter : filters )
            {
                // if a filter rejects then short and continue with outer loop
                if ( !filter.accept( operationContext, tempResult ) )
                {
                    continue outer;
                }
            }

            /*
             * Here the entry has been accepted by all filters.
             */
            prefetched = tempResult;
            ServerEntryUtils.filterContents(
                schemaManager,
                operationContext, prefetched );

            return true;
        }

        prefetched = null;

        return false;
    }


    /**
     * @see Object#toString()
     */
    public String toString( String tabs )
    {
        StringBuilder sb = new StringBuilder();

        if ( wrapped != null )
        {
            sb.append( tabs ).append( "BaseEntryFilteringCursor, wrapped : \n" );
            sb.append( wrapped.toString( tabs + "    " ) );
        }
        else
        {
            sb.append( tabs ).append( "BaseEntryFilteringCursor, no wrapped\n" );
        }

        if ( ( filters != null ) && ( filters.size() > 0 ) )
        {
            sb.append( tabs ).append( "Filters : \n" );

            for ( EntryFilter filter : filters )
            {
                sb.append( filter.toString( tabs + "    " ) ).append( "\n" );
            }
        }
        else
        {
            sb.append( tabs ).append( "No filter\n" );
        }

        if ( prefetched != null )
        {
            sb.append( tabs ).append( "Prefetched : \n" );
            sb.append( prefetched.toString( tabs + "    " ) );
        }
        else
        {
            sb.append( tabs ).append( "No prefetched" );
        }

        return sb.toString();
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        return toString( "" );
    }
}
