/*
 *  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.interceptor.context;


import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.ldap.Control;

import org.apache.directory.server.core.CoreSession;
import org.apache.directory.server.core.LdapPrincipal;
import org.apache.directory.server.core.entry.ClonedServerEntry;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.shared.ldap.entry.Modification;
import org.apache.directory.shared.ldap.name.LdapDN;


/**
 * This abstract class stores common context elements, like the DN, which is used
 * in all the contexts.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public abstract class AbstractOperationContext implements OperationContext
{
    protected static final Control[] EMPTY_CONTROLS = new Control[0];

    /** The DN associated with the context */
    protected LdapDN dn;
    
    /** The entry associated with the target entry of this OperationContext */
    protected ClonedServerEntry entry;
    
    /** The associated request's controls */
    protected Map<String, Control> requestControls = new HashMap<String, Control>(4);

    /** The associated response's controls */
    protected Map<String, Control> responseControls = new HashMap<String, Control>(4);

    /** the Interceptors bypassed by this operation */
    protected Collection<String> byPassed;
    
    protected LdapPrincipal authorizedPrincipal;
    
    /** The core session */
    protected CoreSession session;
    
    protected OperationContext next;
    
    protected OperationContext previous;

    /** A flag used to tell if we should consider referrals as standard entries */
    protected boolean throwReferral;
    
    
    /**
     * Creates a new instance of AbstractOperationContext.
     */
    public AbstractOperationContext( CoreSession session )
    {
        this.session = session;
    }
    
    
    /**
     * Creates a new instance of AbstractOperationContext.
     *
     * @param dn The associated DN
     */
    public AbstractOperationContext( CoreSession session, LdapDN dn )
    {
        this.dn = dn;
        this.session = session;
        
        // The flag is set to ignore, so that the revert operation can act on 
        // the entries, even if they are referrals.
        ignoreReferral();
    }


    public CoreSession getSession()
    {
        return session;
    }
    
    
    protected void setSession( CoreSession session )
    {
        this.session = session;
    }
    
    
    protected void setAuthorizedPrincipal( LdapPrincipal authorizedPrincipal )
    {
        this.authorizedPrincipal = authorizedPrincipal;
    }


    /**
     * @return The associated DN
     */
    public LdapDN getDn()
    {
        return dn;
    }

    
    /**
     * Set the context DN
     *
     * @param dn The DN to set
     */
    public void setDn( LdapDN dn )
    {
        this.dn = dn;
    }

    
    public void addRequestControl( Control requestControl )
    {
        requestControls.put( requestControl.getID(), requestControl );
    }

    
    public Control getRequestControl( String numericOid )
    {
        return requestControls.get( numericOid );
    }

    
    public boolean hasRequestControl( String numericOid )
    {
        return requestControls.containsKey( numericOid );
    }

    
    public boolean hasRequestControls()
    {
        return ! requestControls.isEmpty();
    }


    public void addResponseControl( Control responseControl )
    {
        responseControls.put( responseControl.getID(), responseControl );
    }


    public Control getResponseControl( String numericOid )
    {
        return responseControls.get( numericOid );
    }


    public boolean hasResponseControl( String numericOid )
    {
        return responseControls.containsKey( numericOid );
    }


    public Control[] getResponseControls()
    {
        if ( responseControls.isEmpty() )
        {
            return EMPTY_CONTROLS;
        }
        
        return responseControls.values().toArray( EMPTY_CONTROLS );
    }


    public boolean hasResponseControls()
    {
        return ! responseControls.isEmpty();
    }


    public int getResponseControlCount()
    {
        return responseControls.size();
    }


    public void addRequestControls( Control[] requestControls )
    {
        for ( Control c : requestControls )
        {
            this.requestControls.put( c.getID(), c );
        }
    }

    
    public void setRequestControls( Map<String, Control> requestControls )
    {
        this.requestControls = requestControls;
    }

    
    /**
     * @return the operation name
     */
    public abstract String getName();


    /**
     * Gets the set of bypassed Interceptors.
     *
     * @return the set of bypassed Interceptors
     */
    public Collection<String> getByPassed()
    {
        if ( byPassed == null )
        {
            return Collections.emptyList();
        }
        
        return Collections.unmodifiableCollection( byPassed );
    }
    
    
    /**
     * Sets the set of bypassed Interceptors.
     * 
     * @param byPassed the set of bypassed Interceptors
     */
    public void setByPassed( Collection<String> byPassed )
    {
        this.byPassed = byPassed;
    }

    
    /**
     * Checks to see if an Interceptor is bypassed for this operation.
     *
     * @param interceptorName the interceptorName of the Interceptor to check for bypass
     * @return true if the Interceptor should be bypassed, false otherwise
     */
    public boolean isBypassed( String interceptorName )
    {
        return byPassed != null && byPassed.contains( interceptorName );
    }


    /**
     * Checks to see if any Interceptors are bypassed by this operation.
     *
     * @return true if at least one bypass exists
     */
    public boolean hasBypass()
    {
        return byPassed != null && !byPassed.isEmpty();
    }

    
    private void setup( AbstractOperationContext opContext )
    {
        opContext.setPreviousOperation( this );
        next = opContext;
        opContext.setByPassed( byPassed );
        opContext.setAuthorizedPrincipal( authorizedPrincipal );
    }
    
    
    public boolean hasEntry( LdapDN dn, Collection<String> byPassed ) throws Exception
    {
        EntryOperationContext opContext = new EntryOperationContext( session, dn );
        setup( opContext );
        opContext.setByPassed( byPassed );
        return session.getDirectoryService().getOperationManager().hasEntry( opContext );
    }
    
    
    public void add( ServerEntry entry, Collection<String> byPassed ) throws Exception
    {
        AddOperationContext opContext = new AddOperationContext( session, entry );
        setup( opContext );
        opContext.setByPassed( byPassed );
        session.getDirectoryService().getOperationManager().add( opContext );
    }
    
    
    public void delete( LdapDN dn, Collection<String> byPassed ) throws Exception
    {
        DeleteOperationContext opContext = new DeleteOperationContext( session, dn );
        setup( opContext );
        opContext.setByPassed( byPassed );
        session.getDirectoryService().getOperationManager().delete( opContext );
    }
    
    
    public void modify( LdapDN dn, List<Modification> mods, Collection<String> byPassed ) throws Exception
    {
        ModifyOperationContext opContext = new ModifyOperationContext( session, dn, mods );
        setup( opContext );
        opContext.setByPassed( byPassed );
        session.getDirectoryService().getOperationManager().modify( opContext );
    }
    
    
    // TODO - need synchronization here and where we update links
    public LookupOperationContext newLookupContext( LdapDN dn )
    {
        LookupOperationContext opContext = new LookupOperationContext( session, dn );
        setup( opContext );
        return opContext;
    }


    public ClonedServerEntry lookup( LookupOperationContext opContext ) throws Exception
    {
        if ( opContext != next )
        {
            throw new IllegalStateException( "Cannot execute indirect lookup if it is not the next operation." );
        }
        return session.getDirectoryService().getOperationManager().lookup( opContext );
    }


    public ClonedServerEntry lookup( LdapDN dn, Collection<String> byPassed ) throws Exception
    {
        LookupOperationContext opContext = newLookupContext( dn );
        opContext.setByPassed( byPassed );
        return session.getDirectoryService().getOperationManager().lookup( opContext );
    }
    

    public LdapPrincipal getEffectivePrincipal()
    {
        if ( authorizedPrincipal != null )
        {
            return authorizedPrincipal;
        }
        
        return session.getEffectivePrincipal();
    }
    
    
    // -----------------------------------------------------------------------
    // OperationContext Linked List Methods
    // -----------------------------------------------------------------------
    
    
    public boolean isFirstOperation()
    {
        return previous == null;
    }
    
    
    public OperationContext getFirstOperation()
    {
        if ( previous == null )
        {
            return this;
        }
        
        return previous.getFirstOperation();
    }
    
    
    public OperationContext getLastOperation()
    {
        if ( next == null )
        {
            return this;
        }
        
        return next.getLastOperation();
    }
    
    
    public OperationContext getNextOperation()
    {
        return next;
    }
    
    
    protected void setNextOperation( OperationContext next )
    {
        this.next = next;
    }
    
    
    public OperationContext getPreviousOperation()
    {
        return previous;
    }
    
    
    protected void setPreviousOperation( OperationContext previous )
    {
        this.previous = previous;
    }


    /**
     * @param entry the entry to set
     */
    public void setEntry( ClonedServerEntry entry )
    {
        this.entry = entry;
    }


    /**
     * @return the entry
     */
    public ClonedServerEntry getEntry()
    {
        return entry;
    }
    
    
    /**
     * Set the throwReferral flag to true
     */
    public void throwReferral()
    {
        throwReferral = true;
    }
    
    
    /**
     * @return <code>true</code> if the referrals are thrown
     */
    public boolean isReferralThrown()
    {
        return throwReferral;
    }


    /**
     * Set the throwReferral flag to false
     */
    public void ignoreReferral()
    {
        throwReferral = false;
    }


    /**
     * @return <code>true</code> if the referrals are ignored
     */
    public boolean isReferralIgnored()
    {
        return !throwReferral;
    }
}
