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


import org.apache.directory.server.core.DirectoryServiceConfiguration;
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.shared.ldap.filter.BranchNode;
import org.apache.directory.shared.ldap.filter.SimpleNode;
import org.apache.directory.shared.ldap.message.ModificationItemImpl;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.util.AttributeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import java.util.*;


/**
 * A cache for tracking static group membership.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class GroupCache
{
    /** the attribute id for an object class: objectClass */
    private static final String OC_ATTR = "objectClass";
    /** the member attribute for a groupOfNames: member */
    private static final String MEMBER_ATTR = "member";
    /** the member attribute for a groupOfUniqueNames: uniqueMember */
    private static final String UNIQUEMEMBER_ATTR = "uniqueMember";
    /** the groupOfNames objectClass: groupOfNames */
    private static final String GROUPOFNAMES_OC = "groupOfNames";
    /** the groupOfUniqueNames objectClass: groupOfUniqueNames */
    private static final String GROUPOFUNIQUENAMES_OC = "groupOfUniqueNames";
    /** the logger for this class */
    private static final Logger log = LoggerFactory.getLogger( GroupCache.class );

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

    /** String key for the DN of a group to a Set (HashSet) for the Strings of member DNs */
    private final Map groups = new HashMap();
    /** a handle on the partition nexus */
    private final PartitionNexus nexus;
    /** the env to use for searching */
    private final Hashtable env;

    /**
     * The OIDs normalizer map
     */
    private Map normalizerMap;
    
    /** the normalized dn of the administrators group */
    LdapDN administratorsGroupDn;
    
    /**
     * Creates a static group cache.
     *
     * @param factoryCfg the context factory configuration for the server
     */
    public GroupCache( DirectoryServiceConfiguration factoryCfg ) throws NamingException
    {
    	normalizerMap = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry().getNormalizerMapping();
        this.nexus = factoryCfg.getPartitionNexus();
        this.env = ( Hashtable ) factoryCfg.getEnvironment().clone();
        
        // stuff for dealing with the admin group
        administratorsGroupDn = new LdapDN( "cn=Administrators,ou=groups,ou=system" );
        administratorsGroupDn.normalize( normalizerMap );

        initialize();
    }


    private LdapDN parseNormalized( String name ) throws NamingException
    {
        LdapDN dn = new LdapDN( name );
        dn.normalize( normalizerMap );
        return dn;
    }


    private void initialize() throws NamingException
    {
        // search all naming contexts for static groups and generate
        // normalized sets of members to cache within the map

        BranchNode filter = new BranchNode( BranchNode.OR );
        filter.addNode( new SimpleNode( OC_ATTR, GROUPOFNAMES_OC, SimpleNode.EQUALITY ) );
        filter.addNode( new SimpleNode( OC_ATTR, GROUPOFUNIQUENAMES_OC, SimpleNode.EQUALITY ) );

        Iterator suffixes = nexus.listSuffixes();
        while ( suffixes.hasNext() )
        {
            String suffix = ( String ) suffixes.next();
            LdapDN baseDn = new LdapDN( suffix );
            SearchControls ctls = new SearchControls();
            ctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
            NamingEnumeration results = nexus.search( baseDn, env, filter, ctls );

            while ( results.hasMore() )
            {
                SearchResult result = ( SearchResult ) results.next();
                String groupDn = result.getName();
                groupDn = parseNormalized( groupDn ).toString();
                Attribute members = getMemberAttribute( result.getAttributes() );

                if ( members != null )
                {
                    Set memberSet = new HashSet( members.size() );
                    addMembers( memberSet, members );
                    groups.put( groupDn, memberSet );
                }
                else
                {
                    log.warn( "Found group '" + groupDn + "' without any member or uniqueMember attributes" );
                }
            }
            results.close();
        }

        if ( IS_DEBUG )
        {
            log.debug( "group cache contents on startup:\n" + groups );
        }
    }


    /**
     * Gets the member attribute regardless of whether groupOfNames or
     * groupOfUniqueNames is used.
     *
     * @param entry the entry inspected for member attributes
     * @return the member attribute
     */
    private Attribute getMemberAttribute( Attributes entry )
    {
        Attribute oc = entry.get( OC_ATTR );

        if ( oc == null )
        {
            if ( entry.get( MEMBER_ATTR ) != null )
            {
                return entry.get( MEMBER_ATTR );
            }

            if ( entry.get( UNIQUEMEMBER_ATTR ) != null )
            {
                return entry.get( UNIQUEMEMBER_ATTR );
            }

            return null;
        }

        if ( AttributeUtils.containsValueCaseIgnore( oc, GROUPOFNAMES_OC ) )
        {
            return entry.get( MEMBER_ATTR );
        }

        if ( AttributeUtils.containsValueCaseIgnore( oc, GROUPOFUNIQUENAMES_OC ) )
        {
            return entry.get( UNIQUEMEMBER_ATTR );
        }

        return null;
    }


    /**
     * Adds normalized member DNs to the set of normalized member names.
     *
     * @param memberSet the set of member Dns (Strings)
     * @param members the member attribute values being added
     * @throws NamingException if there are problems accessing the attr values
     */
    private void addMembers( Set memberSet, Attribute members ) throws NamingException
    {
        for ( int ii = 0; ii < members.size(); ii++ )
        {
            // get and normalize the DN of the member
            String memberDn = ( String ) members.get( ii );

            try
            {
                memberDn = parseNormalized( memberDn ).toString();
            }
            catch ( NamingException e )
            {
                log.warn( "Malformed member DN in groupOf[Unique]Names entry.  Member not added to GroupCache.", e );
            }

            memberSet.add( memberDn );
        }
    }


    /**
     * Removes a set of member names from an existing set.
     *
     * @param memberSet the set of normalized member DNs
     * @param members the set of member values
     * @throws NamingException if there are problems accessing the attr values
     */
    private void removeMembers( Set memberSet, Attribute members ) throws NamingException
    {
        for ( int ii = 0; ii < members.size(); ii++ )
        {
            // get and normalize the DN of the member
            String memberDn = ( String ) members.get( ii );

            try
            {
                memberDn = parseNormalized( memberDn ).toString();
            }
            catch ( NamingException e )
            {
                log.warn( "Malformed member DN in groupOf[Unique]Names entry.  Member not removed from GroupCache.", e );
            }

            memberSet.remove( memberDn );
        }
    }


    /**
     * Adds a groups members to the cache.  Called by interceptor to account for new
     * group additions.
     *
     * @param upName the user provided name for the group entry
     * @param normName the normalized name for the group entry
     * @param entry the group entry's attributes
     * @throws NamingException if there are problems accessing the attr values
     */
    public void groupAdded( String upName, Name normName, Attributes entry ) throws NamingException
    {
        Attribute members = getMemberAttribute( entry );

        if ( members == null )
        {
            return;
        }

        Set memberSet = new HashSet( members.size() );
        addMembers( memberSet, members );
        groups.put( normName.toString(), memberSet );
        
        if ( IS_DEBUG )
        {
            log.debug( "group cache contents after adding " + normName.toString() + ":\n" + groups );
        }
    }


    /**
     * Deletes a group's members from the cache.  Called by interceptor to account for
     * the deletion of groups.
     *
     * @param name the normalized DN of the group entry
     * @param entry the attributes of entry being deleted
     */
    public void groupDeleted( Name name, Attributes entry )
    {
        Attribute members = getMemberAttribute( entry );

        if ( members == null )
        {
            return;
        }

        groups.remove( name.toString() );
        
        if ( IS_DEBUG )
        {
            log.debug( "group cache contents after deleting " + name.toString() + ":\n" + groups );
        }
    }


    /**
     * Utility method to modify a set of member names based on a modify operation
     * that changes the members of a group.
     *
     * @param memberSet the set of members to be altered
     * @param modOp the type of modify operation being performed
     * @param members the members being added, removed or replaced
     * @throws NamingException if there are problems accessing attribute values
     */
    private void modify( Set memberSet, int modOp, Attribute members ) throws NamingException
    {

        switch ( modOp )
        {
            case ( DirContext.ADD_ATTRIBUTE  ):
                addMembers( memberSet, members );
                break;
            case ( DirContext.REPLACE_ATTRIBUTE  ):
                if ( members.size() > 0 )
                {
                    memberSet.clear();
                    addMembers( memberSet, members );
                }
                break;
            case ( DirContext.REMOVE_ATTRIBUTE  ):
                removeMembers( memberSet, members );
                break;
            default:
                throw new InternalError( "Undefined modify operation value of " + modOp );
        }
    }


    /**
     * Modifies the cache to reflect changes via modify operations to the group entries.
     * Called by the interceptor to account for modify ops on groups.
     *
     * @param name the normalized name of the group entry modified
     * @param mods the modification operations being performed
     * @param entry the group entry being modified
     * @throws NamingException if there are problems accessing attribute  values
     */
    public void groupModified( Name name, ModificationItemImpl[] mods, Attributes entry ) throws NamingException
    {
        Attribute members = null;
        String memberAttrId = null;
        Attribute oc = entry.get( OC_ATTR );

        if ( AttributeUtils.containsValueCaseIgnore( oc, GROUPOFNAMES_OC ) )
        {
            members = entry.get( MEMBER_ATTR );
            memberAttrId = MEMBER_ATTR;
        }

        if ( AttributeUtils.containsValueCaseIgnore( oc, GROUPOFUNIQUENAMES_OC ) )
        {
            members = entry.get( UNIQUEMEMBER_ATTR );
            memberAttrId = UNIQUEMEMBER_ATTR;
        }

        if ( members == null )
        {
            return;
        }

        for ( int ii = 0; ii < mods.length; ii++ )
        {
            if ( memberAttrId.equalsIgnoreCase( mods[ii].getAttribute().getID() ) )
            {
                Set memberSet = ( Set ) groups.get( name.toString() );
                if ( memberSet != null )
                {
                    modify( memberSet, mods[ii].getModificationOp(), mods[ii].getAttribute() );
                }
                break;
            }
        }
        
        if ( IS_DEBUG )
        {
            log.debug( "group cache contents after modifying " + name.toString() + ":\n" + groups );
        }
    }


    /**
     * Modifies the cache to reflect changes via modify operations to the group entries.
     * Called by the interceptor to account for modify ops on groups.
     *
     * @param name the normalized name of the group entry modified
     * @param modOp the modify operation being performed
     * @param mods the modifications being performed
     * @param entry the entry being modified
     * @throws NamingException if there are problems accessing attribute  values
     */
    public void groupModified( Name name, int modOp, Attributes mods, Attributes entry ) throws NamingException
    {
        Attribute members = getMemberAttribute( mods );

        if ( members == null )
        {
            return;
        }

        Set memberSet = ( Set ) groups.get( name.toString() );
        if ( memberSet != null )
        {
            modify( memberSet, modOp, members );
        }
        
        if ( IS_DEBUG )
        {
            log.debug( "group cache contents after modifying " + name.toString() + ":\n" + groups );
        }
    }

    
    /**
     * An optimization.  By having this method here we can directly access the group
     * membership information and lookup to see if the principalDn is contained within.
     * 
     * @param principalDn the normalized DN of the user to check if they are an admin
     * @return true if the principal is an admin or the admin
     */
    public final boolean isPrincipalAnAdministrator( LdapDN principalDn )
    {
        if ( principalDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
        {
            return true;
        }
        
        Set members = ( Set ) groups.get( administratorsGroupDn.toNormName() );
        if ( members == null )
        {
            log.warn( "What do you mean there is no administrators group? This is bad news." );
            return false;
        }
        
        return members.contains( principalDn.toNormName() );
    }
    

    /**
     * Gets the set of groups a user is a member of.  The groups are returned
     * as normalized Name objects within the set.
     *
     * @param member the member (user) to get the groups for
     * @return a Set of Name objects representing the groups
     * @throws NamingException if there are problems accessing attribute  values
     */
    public Set getGroups( String member ) throws NamingException
    {
        try
        {
            member = parseNormalized( member ).toString();
        }
        catch ( NamingException e )
        {
            log
                .warn(
                    "Malformed member DN.  Could not find groups for member in GroupCache. Returning empty set for groups!",
                    e );
            return Collections.EMPTY_SET;
        }

        Set memberGroups = null;

        Iterator list = groups.keySet().iterator();
        while ( list.hasNext() )
        {
            String group = ( String ) list.next();
            Set members = ( Set ) groups.get( group );

            if ( members == null )
            {
                continue;
            }

            if ( members.contains( member ) )
            {
                if ( memberGroups == null )
                {
                    memberGroups = new HashSet();
                }

                memberGroups.add( new LdapDN( group ) );
            }
        }

        if ( memberGroups == null )
        {
            return Collections.EMPTY_SET;
        }

        return memberGroups;
    }


    public boolean groupRenamed( Name oldName, Name newName )
    {
        Object members = groups.remove( oldName.toString() );

        if ( members != null )
        {
            groups.put( newName.toString(), members );
            
            if ( IS_DEBUG )
            {
                log.debug( "group cache contents after renaming " + oldName.toString() + ":\n" + groups );
            }
            return true;
        }
        return false;
    }
}
