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


import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;


/**
 * Defines a set of zero or more users the permissions apply to.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public abstract class UserClass implements Serializable
{
    private static final long serialVersionUID = -123919984184219893L;

    /**
     * Every directory user (with possible requirements for
     * authenticationLevel).
     */
    public static final AllUsers ALL_USERS = new AllUsers();

    /**
     * The user with the same distinguished name as the entry being accessed, or
     * if the entry is a member of a family, then additionally the user with the
     * distinguished name of the ancestor.
     */
    public static final ThisEntry THIS_ENTRY = new ThisEntry();

    /**
     * The user as parent (ancestor) of accessed entry.
     */
    public static final ParentOfEntry PARENT_OF_ENTRY = new ParentOfEntry();


    /**
     * Creates a new instance.
     */
    protected UserClass()
    {
    }

    /**
     * Every directory user (with possible requirements for
     * authenticationLevel).
     */
    public static class AllUsers extends UserClass
    {
        private static final long serialVersionUID = 8967984720792510292L;


        private AllUsers()
        {
        }


        public String toString()
        {
            return "allUsers";
        }
    }

    /**
     * The user with the same distinguished name as the entry being accessed, or
     * if the entry is a member of a family, then additionally the user with the
     * distinguished name of the ancestor.
     */
    public static class ThisEntry extends UserClass
    {
        private static final long serialVersionUID = -8189325270233754470L;


        private ThisEntry()
        {
        }


        public String toString()
        {
            return "thisEntry";
        }
    }

    /**
     * The user as parent (ancestor) of accessed entry.
     */
    public static class ParentOfEntry extends UserClass
    {
        private static final long serialVersionUID = 5247207736068086476L;


        private ParentOfEntry()
        {
        }


        public String toString()
        {
            return "parentOfEntry";
        }

    }

    /**
     * A base class for all user classes which has a set of DNs.
     */
    private static abstract class NamedUserClass extends UserClass
    {
        private static final long serialVersionUID = 8571875984468893621L;
        protected final Set<DN> names;


        /**
         * Creates a new instance.
         * 
         * @param names a set of names
         */
        protected NamedUserClass( Set<DN> names )
        {
            if ( names == null )
            {
                this.names = Collections.unmodifiableSet( new HashSet<DN>() );
            }
            else
            {
                this.names = Collections.unmodifiableSet( new HashSet<DN>( names ) );
            }
        }


        /**
         * Returns the set of all names.
         */
        public Set<DN> getNames()
        {
            return names;
        }


        /**
         * {@inheritDoc}
         */
        @Override
        public boolean equals( Object o )
        {
            if ( this == o )
            {
                return true;
            }

            if ( o == null )
            {
                return false;
            }

            if ( getClass().isAssignableFrom( o.getClass() ) )
            {
                Name that = ( Name ) o;
                return this.names.equals( that.names );
            }

            return false;
        }


        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode()
        {
            int result = 37;

            for ( DN dn : this.names )
            {
                result = result * 17 + dn.hashCode();
            }

            return result;
        }


        public String toString()
        {
            StringBuilder buffer = new StringBuilder();

            boolean isFirst = true;
            buffer.append( "{ " );

            for ( DN name : names )
            {
                if ( isFirst )
                {
                    isFirst = false;
                }
                else
                {
                    buffer.append( ", " );
                }

                buffer.append( '"' );
                buffer.append( name.toString() );
                buffer.append( '"' );
            }

            buffer.append( " }" );

            return buffer.toString();
        }
    }

    /**
     * The user with the specified distinguished name.
     */
    public static class Name extends NamedUserClass
    {
        private static final long serialVersionUID = -4168412030168359882L;


        /**
         * Creates a new instance.
         * 
         * @param usernames
         *            the set of user DNs.
         */
        public Name( Set<DN> usernames )
        {
            super( usernames );
        }


        public String toString()
        {
            return "name " + super.toString();
        }
    }

    /**
     * The set of users who are members of the groupOfUniqueNames entry,
     * identified by the specified distinguished name. Members of a group of
     * unique names are treated as individual object names, and not as the names
     * of other groups of unique names.
     */
    public static class UserGroup extends NamedUserClass
    {
        private static final long serialVersionUID = 8887107815072965807L;


        /**
         * Creates a new instance.
         * 
         * @param groupNames
         *            the set of group DNs.
         */
        public UserGroup( Set<DN> groupNames )
        {
            super( groupNames );
        }


        public String toString()
        {
            return "userGroup " + super.toString();
        }
    }

    /**
     * The set of users whose distinguished names fall within the definition of
     * the (unrefined) subtree.
     */
    public static class Subtree extends UserClass
    {
        private static final long serialVersionUID = 3949337699049701332L;

        protected final Set<SubtreeSpecification> subtreeSpecifications;


        /**
         * Creates a new instance.
         * 
         * @param subtreeSpecs
         *            the collection of unrefined {@link SubtreeSpecification}s.
         */
        public Subtree( Set<SubtreeSpecification> subtreeSpecs )
        {
            this.subtreeSpecifications = Collections.unmodifiableSet( subtreeSpecs );
        }


        /**
         * Returns the collection of unrefined {@link SubtreeSpecification}s.
         */
        public Set<SubtreeSpecification> getSubtreeSpecifications()
        {
            return subtreeSpecifications;
        }


        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode()
        {
            int hash = 37;
            hash = hash * 17 + subtreeSpecifications.hashCode();

            return hash;
        }


        /**
         * {@inheritDoc}
         */
        @Override
        public boolean equals( Object o )
        {
            if ( this == o )
            {
                return true;
            }

            if ( o instanceof Subtree )
            {
                Subtree that = ( Subtree ) o;
                return this.subtreeSpecifications.equals( that.subtreeSpecifications );
            }

            return false;
        }


        public String toString()
        {
            StringBuilder buffer = new StringBuilder();

            boolean isFirst = true;
            buffer.append( "subtree { " );

            for ( SubtreeSpecification ss : subtreeSpecifications )
            {
                if ( isFirst )
                {
                    isFirst = false;
                }
                else
                {
                    buffer.append( ", " );
                }

                ss.toString( buffer );
            }

            buffer.append( " }" );

            return buffer.toString();
        }
    }
}
