/*******************************************************************************
 * Copyright (c), 2001, 2002 N2 Broadband, Inc.  All Rights Reserved.
 *
 * This module contains unpublished, confidential, proprietary
 * material.  The use and dissemination of this material are
 * governed by a license.  The above copyright notice does not
 * evidence any actual or intended publication of this material.
 *
 * Author:  Drake H. Henderson
 * Created:  11-12-01
 *
 ******************************************************************************/

package com.n2bb.security;

/**** COMMON IMPORTS BEGIN ****/
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import com.n2bb.action.N2bbAction;
import com.n2bb.user.UserBean;
import com.n2bb.util.ActionConstants;
import com.tandbergtv.workflow.auth.ACLEntry;
import com.tandbergtv.workflow.auth.AuthorizationManager;
import com.tandbergtv.workflow.auth.IAuthorizationManager;
import com.tandbergtv.workflow.auth.Permission;
import com.tandbergtv.workflow.auth.Role;
import com.tandbergtv.workflow.resourcemanager.ResourceManagement;
import com.tandbergtv.workflow.resourcemanager.ResourceManager;
import com.tandbergtv.workflow.resourcemanager.entities.Resource;
import com.tandbergtv.workflow.web.common.StaticCodes;

public final class RolesAction extends N2bbAction {


  public ActionForward execute(ActionMapping mapping, ActionForm form,
          HttpServletRequest request,
          HttpServletResponse response)throws Exception {

    // defaultAction
    String defaultAction = ActionConstants.add;

    /******************** COMMON BEGIN *********************/
    HttpSession session = request.getSession();

    String action = request.getParameter("actionType");
    if (request.getAttribute("actionType") != null){
    	
    	action = (String)request.getAttribute("actionType");
    }
    if (action == null || action.equals(""))
      action = defaultAction;
    n2bbLog.debug("action... " + action);

    ActionErrors errors = new ActionErrors();
    ActionForward fwd = new ActionForward("home");
    /******************** COMMON END ***********************/

    try {
      RoleForm rf = (RoleForm)form;

      // add role
      if (action.equals(ActionConstants.add)) {
        if (addRole(errors, session))
          fwd = mapping.findForward("success");
        else
          fwd = mapping.findForward("failure");
      // save role
      } else if (action.equals(ActionConstants.save)) {
        if (saveRole(errors, rf)) {
        	request.setAttribute(ActionConstants.save,ActionConstants.save);
          	return mapping.findForward("success");
        } else
          fwd = mapping.findForward("failure");
      // edit role
      } else if (action.equals(ActionConstants.edit)) {
        if (editRole(errors, session, request,form)){
        	
    		// For displaying Modify tab item in the menu.
    		request.setAttribute(StaticCodes.MODIFY_TAB_ITEM,
    				StaticCodes.MODIFY_TAB_ITEM);
    		
        	fwd = mapping.findForward("success");
        }
        else
          fwd = mapping.findForward("failure");
      // update role
      } else if (action.equals(ActionConstants.update)) {
        if (updateRole(errors, rf)) {
        	request.setAttribute(ActionConstants.update,ActionConstants.update);
         return mapping.findForward("success");
       } else{
			ActionMessages actionMessages = new ActionMessages();
			actionMessages.add(StaticCodes.PERFORM_TASK_PERMISSION_REQUIRED,
					new ActionMessage(StaticCodes.PERFORM_TASK_PERMISSION_REQUIRED, true));
			saveMessages(request, actionMessages);
			request.setAttribute("actionType",ActionConstants.edit);
          return mapping.findForward("failure");
       }
      }
    } catch (Exception e) {
      n2bbLog.error("exception - message... " + e.getMessage(), e);
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.other"));
    }

    if (!errors.isEmpty())
      saveErrors(request, errors);

    return fwd;
  }

  /***************************************
   *
   ***************************************/
  private boolean addRole(ActionErrors errors, HttpSession session) {
    n2bbLog.debug("enter");

    try {
      session.setAttribute("moduleAreaLists", SecurityManager.getInstance().getModuleAreaLists());
      return true;

    } catch (Exception e) {
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.roleAction.add"));
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.other"));
      n2bbLog.error(e.getMessage(), e);
      return false;
    }
  }

  /***************************************
   *
   ***************************************/
  private boolean saveRole(ActionErrors errors, RoleForm form) {
    n2bbLog.debug("enter");
    try {
    	IAuthorizationManager authorizationManager = AuthorizationManager.getInstance();
      	Map<String,String> permissionsMap = form.getPermissionMap();
      	n2bbLog.debug("Permissions Map -->"+permissionsMap);
      	n2bbLog.debug("Role Name-->"+form.getN2RoleName()+":: Description--->"+form.getDescription());
      	Role role = new Role(form.getN2RoleName(),form.getDescription());
      	Set permissions  = permissionsMap.entrySet();
      	for (Iterator iter = permissions.iterator(); iter.hasNext();) {
			Entry element = (Entry) iter.next();
			role.addACL(new ACLEntry(role, new Permission(Long.parseLong(element.getValue().toString()))));
		}
      	authorizationManager.createRole(role);
        return true;
    }
    catch (Exception e) {
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.roleAction.save"));
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.other"));
      n2bbLog.error(e.getMessage(), e);
      return false;
    }
    
  }

  /***************************************
   *
   ***************************************/
  private boolean editRole(ActionErrors errors, HttpSession session,
          HttpServletRequest request, ActionForm actionForm) {
    n2bbLog.debug("enter");

    try {
      
      // get role
      String n2RoleName = request.getParameter("n2RoleName");
      n2bbLog.debug("role name... " + n2RoleName);
     
      // Get from the form bean if n2RoleName is null 
      if (n2RoleName == null){
    	  n2RoleName = ((RoleForm)actionForm).getN2RoleName();
      }
      try {
    	IAuthorizationManager authorizationManager = AuthorizationManager.getInstance();
    	Role role = authorizationManager.getRole(n2RoleName);
    	String[] permissions = new String[role.getACL().size()];
    	n2bbLog.debug("The permissions size --->"+ role.getACL().size());
    	Iterator<ACLEntry> aclEntryIterator = role.getACL().iterator();
    	int count = 0;
    	while(aclEntryIterator.hasNext()) {
			permissions[count++] = String.valueOf(aclEntryIterator.next().getPermission().getId());
		}
    	RoleForm form = new RoleForm();
    	form.setN2RoleName(role.getName());
    	form.setDescription(role.getDescription());
    	form.setPermissions(permissions);
        form.setAction(ActionConstants.edit);
        SecurityManager securityManager = SecurityManager.getInstance();
        form.setUsers(securityManager.getUserData(role.getName()));
        request.setAttribute("roleForm", form);
      } catch (Exception e) {
        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.roleAction.edit"));
       n2bbLog.error("failed to get role exception - message... " + e.getMessage(), e);
        return false;
      }

      return true;
    } 
    catch (Exception e) {
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.roleAction.edit"));
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.other"));
      n2bbLog.error(e.getMessage(), e);
      return false;
    }
  }

  /************************
   *
   ************************/
  private boolean updateRole(ActionErrors errors, RoleForm form) {
    n2bbLog.debug("enter");

    try {
       	ResourceManagement resourceManager = ResourceManager.getInstance();
    	// Getting the Role object from the DB
    	IAuthorizationManager authorizationManager = AuthorizationManager.getInstance();
    	SecurityManager securityManager = SecurityManager.getInstance();
       	Role role = authorizationManager.getRole(form.getN2RoleName());
       	role.setDescription(form.getDescription());
    	Set<ACLEntry> setACLEntries = role.getACL();
    	long performTaskId = 0; 
    	
    	// Getting the Perform Task Permission id 
    	for (ACLEntry entry : setACLEntries){
    		if(entry.getPermission().getName().equalsIgnoreCase(StaticCodes.PERMISSION_NAME_PERFORM_TASK)){
    			performTaskId=entry.getPermission().getId();
    			break;
    		}
    	}
    	// clear the previous permissions for this role
    	role.getACL().clear();
    	n2bbLog.debug("Permission IDs-->");
    	
    	// Get the Permission map
      	Map<String,String> permissionsMap = form.getPermissionMap();
      	
      	boolean performTaskPermissionStatus = false;
      	boolean isResourceExists = false;
      	
      	if (performTaskId != 0){
      	
      		// check for the human resource with the this role
      		Set<UserBean> users =  securityManager.getUserData(role.getName());
      		for (UserBean user : users){
      			if (resourceManager.getResourceByUser(user.getUserName()) != null) {
      				isResourceExists = true;
      				break;
      			}
      		}
      		
      		// check for the Perform Task permission id in the new permissions map
      		if (isResourceExists){
		      	for (Entry<String,String> entry : permissionsMap.entrySet()){
		      		if (Long.parseLong(entry.getValue().toString()) == performTaskId){
		      			performTaskPermissionStatus = true;
		      			break;
		      		}
		      	}
		      	// return false if there is no Perform Task Permission
		      	if (performTaskPermissionStatus == false){
		      		return false;
		      	}
      		}
      	}
      	
      	n2bbLog.debug("Permissions Map -->"+permissionsMap);
      	n2bbLog.debug("Role Name-->"+form.getN2RoleName()+":: Description--->"+form.getDescription());
      	
      	// add permissions to the role as an ACL entries
      	Set permissions  = permissionsMap.entrySet();
      	for (Iterator iter = permissions.iterator(); iter.hasNext();) {
			Entry element = (Entry) iter.next();
			role.addACL(new ACLEntry(role, new Permission(Long.parseLong(element.getValue().toString()))));
		}
     	
      	// update the role into the db
      	authorizationManager.updateRole(role);
      return true;
    }
    catch (Exception e) {
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.roleAction.update"));
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.other"));
      n2bbLog.error(e.getMessage(), e);
      return false;
    }
  }

}

