/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.ui.api.useraccess;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Action;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Group;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Permission;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Type;

// TODO: Auto-generated Javadoc
/**
 * The Class ARoleAuthorizationGroup.
 */
public abstract class AbstractRoleAuthorizationGroup {

	/** The permissions. */
	private Map<String,Boolean> fPermissions = new HashMap<>(); 

	/**
	 * Instantiates a new a role authorization group.
	 *
	 * @param permissionSets the permission sets
	 */
	@SafeVarargs
	protected AbstractRoleAuthorizationGroup(Set<Permission>... permissionSets) {
		for (Set<Permission> permissionSet : permissionSets) {
			for (Permission permission : permissionSet) {
				fPermissions.put(permission.toString(), permission.isPermitted());
			}
		}
	}
	
	/**
	 * Adds the permission.
	 *
	 * @param permission the permission
	 */
	public final void addPermission(Permission permission) {
		fPermissions.put(permission.toString(), permission.isPermitted());
	}

	/**
	 * Gets the name.
	 *
	 * @return the name
	 */
	public final String getName() {
		return getRoleName();
	}
	
	/**
	 * Gets the role name.
	 *
	 * @return the role name
	 */
	public final String getRoleName() {
		return this.getClass().getSimpleName();
	}
	
//	final public Map<String,Boolean> getPermissions() { // NOSONAR
//		return fPermissions; // NOSONAR
//	} // NOSONAR
	
	/**
 * Gets the permission keys.
 *
 * @return the permission keys
 */
public final Set<String> getPermissionKeys() {
		return fPermissions.keySet();
	}
	
	/**
	 * Exists permission keys.
	 *
	 * @param key the key
	 * @return true, if successful
	 */
	public final boolean existsPermissionKeys(String key) {
		return fPermissions.containsKey(key);
	}
	
	/**
	 * Gets the permission.
	 *
	 * @param key the key
	 * @return the permission
	 */
	public final boolean getPermission(String key) {
		return fPermissions.get(key);
	}

	/**
	 * Granted.
	 *
	 * @param group the group
	 * @param clas the clas
	 * @param actions the actions
	 * @return the sets the
	 */
	public static final Set<Permission> granted(Group group, String clas, Action... actions) {
		Set<Permission> granted = new HashSet<>();
		// --- any default authorizations ---
		if  (group.hasDefaultAction()) {
			granted.add(new Permission(group, clas, group.getDefaultAction()));
		}
		// --- if the ANY-authorization is given ---
		if  ((actions.length == 1) && actions[0].equals(Action.any)) {
			for (Action anyAction : group.getAnyActions()) {
				granted.add(new Permission(group, clas, anyAction));
			}
		}
		else { 
			// --- every authorization explizit ---
			for (Action action : actions) {
				granted.add(new Permission(group, clas, action));
			}
		}
		return granted;
	}
	
	/**
	 * Granted.
	 *
	 * @param group the group
	 * @param clas the clas
	 * @param attribute the attribute
	 * @param actions the actions
	 * @return the sets the
	 */
	public static final Set<Permission> granted(Group group, String clas, String attribute, Action... actions) {
		Set<Permission> granted = new HashSet<>();
		for (Action action : actions) {
			// --- if the action has auto granted actions ---
			if  (action.hasAutoGrantedActions()) {
				for (Action autoGrantedAction : action.getAutoGrantedActions()) {
					granted.add(new Permission(Type.GRANT, group, clas, attribute, autoGrantedAction));
				}
			}
			// --- grant the action itself ---
			granted.add(new Permission(Type.GRANT, group, clas, attribute, action));
		}
		return granted;
	}
	
	/**
	 * Denied.
	 *
	 * @param group the group
	 * @param clas the clas
	 * @param attribute the attribute
	 * @param actions the actions
	 * @return the sets the
	 */
	public static final Set<Permission> denied(Group group, String clas, String attribute, Action... actions) {
		Set<Permission> denied = new HashSet<>();
		for (Action action : actions) {
			// --- if the action has auto denied actions ---
			if  (action.hasAutoDeniedActions()) {
				for (Action autoDeniedAction : action.getAutoDeniedActions()) {
					denied.add(new Permission(Type.DENY, group, clas, attribute, autoDeniedAction));
				}
			}
			// --- deny the action itself ---
			denied.add(new Permission(Type.DENY, group, clas, attribute, action));
		}
		return denied;
	}
	
}
