/*
 *   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.fortress.core.model;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;

import org.apache.commons.lang.StringUtils;
import org.apache.directory.fortress.core.util.Config;


/**
 * The Fortress UserRole entity is used to store an RBAC User to Role assignment along with its temporal constraint
 * values.
 * The contents of the UserRole entity will be stored on the User entity in the 'ftRA' (Role name) and 'ftRC'
 * (Temporal Constraints) attributes on the 'ftUserAttrs' object class.
 * The UserRole entity carries elements of {@link Constraint}.  Any attributes of
 * Constraint not set within this entity
 * will use same attribute from the {@link org.apache.directory.fortress.core.model.Role} entity.  Thus the UserRole can override
 * Constraint attributes from it's corresponding Role if required by caller.
 * <p>
 * <h4>UserRole Schema</h4>
 * ftUserAttrs is used to store RBAC and ARBAC Role role assignments and other security attributes on User entity.
 * <pre>
 * ------------------------------------------
 * Fortress User Attributes Auxiliary Object Class
 * objectclass ( 1.3.6.1.4.1.38088.3.1
 *  NAME 'ftUserAttrs'
 *  DESC 'Fortress User Attribute AUX Object Class'
 *  AUXILIARY
 *  MUST (
 *      ftId
 *  )
 *  MAY (
 *      ftRC $
 *      ftRA $
 *      ftARC $
 *      ftARA $
 *      ftCstr $
 *      ftSystem
 *  )
 * )
 * ------------------------------------------
 * </pre>
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@XmlRootElement( name = "fortUserRole" )
@XmlAccessorType( XmlAccessType.FIELD )
@XmlType(
    name = "userRole",
    propOrder = {
        "name",
        "userId",
        "isGroupRole",
        "parents",
        "beginDate",
        "beginLockDate",
        "beginTime",
        "dayMask",
        "endDate",
        "endLockDate",
        "endTime",
        "timeout",
        "roleConstraints"}
)
@XmlSeeAlso( {UserAdminRole.class} )
public class UserRole extends FortEntity implements Serializable, Constraint
{
    private static final long serialVersionUID = 1L;
    
    protected String userId;
    protected String name;
    protected boolean isGroupRole;
    private Integer timeout;
    private String beginTime;
    private String endTime;
    private String beginDate;
    private String endDate;
    private String beginLockDate;
    private String endLockDate;
    private String dayMask;
    private Set<String> parents;
    private List<RoleConstraint> roleConstraints;

    /**
     * Default constructor is used by internal Fortress classes.
     */
    public UserRole()
    {
    }


    /**
     * Construct a UserRole entity given the required attributes 'userId' and 'role' name.
     *
     * @param userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
     * @param role   maps to the 'ftRA' attribute on the 'ftUserAttrs' object class.
     */
    public UserRole( String userId, String role )
    {
        this.userId = userId;
        name = role;
        isGroupRole = false;
    }

    /**
     * Construct a UserRole entity given the required attributes 'userId' and 'role' name.
     *
     * @param userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
     * @param name role name, maps to the 'ftRA' attribute on the 'ftUserAttrs' object class.
     * @param isGroupRole defines if value contained in userId is group name rather than user's uid
     */
    public UserRole(String userId, String name, boolean isGroupRole) {
        this.userId = userId;
        this.name = name;
        this.isGroupRole = isGroupRole;
    }

    /**
     * Construct an RBAC Role with required attribute 'userId' and optional temporal constraint.
     *
     * @param userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
     * @param con    maps to 'ftRC' attribute in 'ftUserAttrs' object class.
     */
    public UserRole( String userId, Constraint con )
    {
        this.userId = userId;
        isGroupRole = false;
        ConstraintUtil.copy( con, this );
    }


    /**
     * Construct a UserRole entity given the required attribute role' name.
     *
     * @param role maps to the 'ftRA' attribute on the 'ftUserAttrs' object class.
     */
    public UserRole( String role )
    {
        name = role;
    }

    /**
     * This method loads UserRole entity temporal constraint instance variables with data that was retrieved from the
     * 'ftRC' attribute on the 'ftUserAttrs' object class.  This is the raw format that Fortress uses to condense the
     * temporal data into
     * a compact String for efficient storage and retrieval and is not intended to be called by external programs.
     *
     * @param szRawData contains a raw formatted String that maps to 'ftRC' attribute on 'ftUserAttrs' object class
     * @param contextId contains the tenant id.
     * @param parentUtil provides method to getParents.
     */
    public void load( String szRawData, String contextId, ParentUtil parentUtil )
    {
        if ( ( szRawData != null ) && ( szRawData.length() > 0 ) )
        {
            String[] tokens = StringUtils.splitPreserveAllTokens( szRawData, Config.getInstance().getDelimiter() );
            
            //newer style constaint type
            if(tokens[1].equals(RoleConstraint.RC_TYPE_NAME)){
                RoleConstraint rc = new RoleConstraint(tokens[5], tokens[4], RoleConstraint.RCType.valueOf( tokens[2] ),
                    tokens[3]);
                this.getRoleConstraints().add(rc);
            }
            else{
                for ( int i = 0; i < tokens.length; i++ )
                {
                    if ( StringUtils.isNotEmpty( tokens[i] ) )
                    {
                        switch ( i )
                        {
                            case 0:
                                name = tokens[i];
                                parents = parentUtil.getParentsCB( name.toUpperCase(), contextId );
                                break;
    
                            case 1:
                                timeout = Integer.parseInt( tokens[i] );
                                break;
    
                            case 2:
                                beginTime = tokens[i];
                                break;
    
                            case 3:
                                endTime = tokens[i];
                                break;
    
                            case 4:
                                beginDate = tokens[i];
                                break;
    
                            case 5:
                                endDate = tokens[i];
                                break;
    
                            case 6:
                                beginLockDate = tokens[i];
                                break;
    
                            case 7:
                                endLockDate = tokens[i];
                                break;
    
                            case 8:
                                dayMask = tokens[i];
                                break;
                        }
                    }
                }
            }
        }
    }


    /**
     * Required on DAO classes convert Temporal attributes stored on entity to raw data object format needed for ldap
     * .  For internal use only.
     *
     * @return String that maps to 'ftRA' attribute on the 'ftUserAttrs' object class.
     */
    @Override
    public String getRawData()
    {
        String delimeter = Config.getInstance().getDelimiter();
        StringBuilder sb = new StringBuilder();

        sb.append( name );
        sb.append( delimeter );
        sb.append( timeout );
        sb.append( delimeter );

        if ( beginTime != null )
        {
            sb.append( beginTime );
        }

        sb.append( delimeter );

        if ( endTime != null )
        {
            sb.append( endTime );
        }

        sb.append( delimeter );

        if ( beginDate != null )
        {
            sb.append( beginDate );
        }

        sb.append( delimeter );

        if ( endDate != null )
        {
            sb.append( endDate );
        }

        sb.append( delimeter );

        if ( beginLockDate != null )
        {
            sb.append( beginLockDate );
        }

        sb.append( delimeter );

        if ( endLockDate != null )
        {
            sb.append( endLockDate );
        }

        sb.append( delimeter );

        if ( dayMask != null )
        {
            sb.append( dayMask );
        }

        return sb.toString();
    }


    /**
     * Return the userId that is associated with UserRole.  UserId is required attribute and must be set on all
     * UserRole assignment operations.
     *
     * @return attribute maps to 'uid' in 'inetOrgPerson' object class.
     */
    public String getUserId()
    {
        return userId;
    }


    /**
     * Set the userId that is associated with UserRole.  UserId is required attribute and must be set on all UserRole
     * assignment operations.
     *
     * @param userId maps to 'uid' in 'inetOrgPerson' object class.
     */
    public void setUserId( String userId )
    {
        this.userId = userId;
    }


    /**
     * Get the Role name required attribute of the UserRole object
     *
     * @param name maps to 'ftRC' and 'ftRA' attributes on 'ftUserAttrs' object class.
     */
    @Override
    public void setName( String name )
    {
        this.name = name;
    }


    /**
     * Set the Role name required attribute of the UserRole object
     *
     * @return attribute maps to 'ftRC' and 'ftRA' attributes on 'ftUserAttrs' object class.
     */
    @Override
    public String getName()
    {
        return name;
    }


    /**
     * temporal boolean flag is used by internal Fortress components.
     *
     * @return boolean indicating if temporal constraints are placed on UserRole.
     */
    @Override
    public boolean isTemporalSet()
    {
        return ( beginTime != null || endTime != null || beginDate != null || endDate != null || beginLockDate !=
            null || endLockDate != null || dayMask != null );
    }


    /**
     * Set the integer timeout that contains max time ((in minutes)) that entity may remain inactive.
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param timeout maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setTimeout( Integer timeout )
    {
        this.timeout = timeout;
    }


    /**
     * Set the begin time of day entity is allowed to be activated in system.  The format is military time - HHMM,
     * i.e. 0800 (8:00 am) or 1700 (5:00 p.m.).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param beginTime maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setBeginTime( String beginTime )
    {
        this.beginTime = beginTime;
    }


    /**
     * Set the end time of day entity is allowed to be activated in system.  The format is military time - HHMM,
     * i.e. 0000 (12:00 am) or 2359 (11:59 p.m.).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param endTime maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setEndTime( String endTime )
    {
        this.endTime = endTime;
    }


    /**
     * Set the beginDate when entity is allowed to be activated in system.  The format is - YYYYMMDD,
     * i.e. 20100101 (January 1, 2001).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param beginDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setBeginDate( String beginDate )
    {
        this.beginDate = beginDate;
    }


    /**
     * Set the end date when entity is not allowed to be activated in system.  The format is - YYYYMMDD,
     * i.e. 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param endDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setEndDate( String endDate )
    {
        this.endDate = endDate;
    }


    /**
     * Set the daymask that specifies what days of week entity is allowed to be activated in system.  The format is
     * 1234567, i.e. 23456 (Monday, Tuesday, Wednesday, Thursday, Friday).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param dayMask maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setDayMask( String dayMask )
    {
        this.dayMask = dayMask;
    }


    /**
     * Set the begin lock date when entity is temporarily not allowed to be activated in system.  The format is -
     * YYYYMMDD, 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param beginLockDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setBeginLockDate( String beginLockDate )
    {
        this.beginLockDate = beginLockDate;
    }


    /**
     * Set the end lock date when entity is allowed to be activated in system once again.  The format is - YYYYMMDD,
     * i.e. 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @param endLockDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public void setEndLockDate( String endLockDate )
    {
        this.endLockDate = endLockDate;
    }


    /**
     * Return the integer timeout that contains total time ((in minutes)) that entity may remain inactive.
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return int that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public Integer getTimeout()
    {
        return timeout;
    }


    /**
     * Contains the begin time of day entity is allowed to be activated in system.  The format is military time -
     * HHMM, i.e. 0800 (8:00 am) or 1700 (5:00 p.m.).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getBeginTime()
    {
        return beginTime;
    }


    /**
     * Contains the end time of day entity is allowed to be activated in system.  The format is military time - HHMM,
     * i.e. 0000 (12:00 am) or 2359 (11:59 p.m.).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getEndTime()
    {
        return endTime;
    }


    /**
     * Contains the begin date when entity is allowed to be activated in system.  The format is - YYYYMMDD,
     * i.e. 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getBeginDate()
    {
        return beginDate;
    }


    /**
     * Contains the end date when entity is allowed to be activated in system.  The format is - YYYYMMDD,
     * i.e. 20101231 (December 31, 2011).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getEndDate()
    {
        return endDate;
    }


    /**
     * Contains the begin lock date when entity is temporarily not allowed to activated in system.  The format is -
     * YYYYMMDD, i.e. 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getBeginLockDate()
    {
        return beginLockDate;
    }


    /**
     * Contains the end lock date when entity is allowed to be activated in system once again.  The format is -
     * YYYYMMDD, i.e. 20100101 (January 1. 2010).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getEndLockDate()
    {
        return endLockDate;
    }


    /**
     * Get the daymask that indicates what days of week entity is allowed to be activated in system.  The format is 1234567, i.e. 23456 (Monday, Tuesday, Wednesday, Thursday, Friday).
     * This attribute is optional but if set will be validated for reasonableness.
     *
     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
     */
    @Override
    public String getDayMask()
    {
        return dayMask;
    }


    @Override
    public List<RoleConstraint> getConstraints()
    {
        return getRoleConstraints();
    }

    /**
     * Get the names of roles that are parents (direct ascendants) of this role.
     *
     * @return Set of parent role names assigned to this role.
     */
    public Set<String> getParents()
    {
        return parents;
    }


    /**
     * Set the names of roles names that are parents (direct ascendants) of this role.
     *
     * @param parents contains the Set of parent role names assigned to this role.
     */
    public void setParents( Set<String> parents )
    {
        this.parents = parents;
    }

    /**
     * Returns 'true' if value in userId refers to group name
     * @return if userId contains group name
     */
    public boolean isGroupRole() {
        return isGroupRole;
    }

    /**
     * Set to 'true' if userId contains group name
     * @param groupRole specifies if value in userId contains group name
     */
    public void setGroupRole(boolean groupRole) {
        isGroupRole = groupRole;
    }

    /**
     * Matches the userId and role name from two UserRole entities.
     *
     * @param thatObj contains a UserRole entity.
     * @return boolean indicating both objects contain matching userId and Role names.
     */
    public boolean equals( Object thatObj )
    {
        if ( this == thatObj )
        {
            return true;
        }

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

        if ( !( thatObj instanceof UserRole ) )
        {
            return false;
        }

        UserRole thatRole = ( UserRole ) thatObj;

        if ( thatRole.getName() == null )
        {
            return false;
        }

        return ( thatRole.getName().equalsIgnoreCase( name ) );
    }

    @Override
    public int hashCode()
    {
        int result = userId != null ? userId.hashCode() : 0;
        result = 31 * result + ( name != null ? name.hashCode() : 0 );
        result = 31 * result + ( timeout != null ? timeout.hashCode() : 0 );
        result = 31 * result + ( beginTime != null ? beginTime.hashCode() : 0 );
        result = 31 * result + ( endTime != null ? endTime.hashCode() : 0 );
        result = 31 * result + ( beginDate != null ? beginDate.hashCode() : 0 );
        result = 31 * result + ( endDate != null ? endDate.hashCode() : 0 );
        result = 31 * result + ( beginLockDate != null ? beginLockDate.hashCode() : 0 );
        result = 31 * result + ( endLockDate != null ? endLockDate.hashCode() : 0 );
        result = 31 * result + ( dayMask != null ? dayMask.hashCode() : 0 );
        result = 31 * result + ( parents != null ? parents.hashCode() : 0 );
        return result;
    }

    /**
     * Used to retrieve UserRole Role name attribute.  The Fortress UserRole name maps to 'ftRA' attribute on
     * 'ftUserAttrs' object class.
     */
    @Override
    public String toString()
    {
        return name;
    }


    public List<RoleConstraint> getRoleConstraints()
    {
        if(roleConstraints == null)
        {
            roleConstraints = new ArrayList();
        }
        return roleConstraints;
    }


    public void setRoleConstraints(List<RoleConstraint> roleConstraints) {
        this.roleConstraints = roleConstraints;
    }
}
