package gov.va.med.authentication.kernel;

import java.util.ArrayList;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.apache.log4j.Level; 

import gov.va.med.vistalink.adapter.cci.VistaLinkConnection;
import gov.va.med.vistalink.rpc.RpcRequest;
import gov.va.med.vistalink.rpc.RpcRequestFactory;
import gov.va.med.vistalink.rpc.RpcResponse;
import gov.va.med.exception.FoundationsException;

/**
 * Business Delegate that handles the details of caching a user's roles.
 * @author VHIT Security and Other Common Services (S&OCS)
 * @version 1.1.0.007
 */
class RoleUtils {

	private static final Logger LOGGER = Logger.getLogger(RoleUtils.class);

	/**
	 * Cache a user's roles. Called during login to a) retrieve a user's roles from VistA, matching a the
	 * roles found in the RoleSingleton object, and b) cache those roles in the role cache table for the 
	 * current DAO implementation in use.
	 * @param username
	 * @param myConnection
	 * @param ApplicationRoleListVOSingleton
	 * @return
	 * @throws FoundationsException
	 */
	static void cacheRoles(
		String username,
		VistaLinkConnection myConnection,
		ApplicationRoleListVOSingleton roleListVO)
		throws KaajeeException {

		/*DAOFactory myDAOFactory = DAOFactory.getDAOFactory();
		ILoginRoleDAO roleDAO = myDAOFactory.getLoginRoleDAO();

		//1. Flush current roles for this username
		roleDAO.flushRoles(username);
		if (LOGGER.isEnabledFor(Level.DEBUG)) {
			LOGGER.debug("finished flushing roles.");
		}

		if (LOGGER.isEnabledFor(Level.DEBUG)) {
			LOGGER.debug("now retrieving roles.");
		}
 	*/
		// 2. get application role set, here getting groupnames from kaajeeconfig.xml file   
		/*ArrayList appRoleList = roleListVO.getRoleList();
		if (appRoleList.size() < 1) {

			String exceptionMessage = "No roles found for application.";
			if (LOGGER.isEnabledFor(Level.ERROR)) {
				LOGGER.error(exceptionMessage);
			}
			throw new KaajeeException(exceptionMessage);

		}
*/
		// TODO separate this M call into a separate method returning an arraylist
		
		//3. Retrieve any matching roles for this username from M
		ArrayList userRoleListFromM = new ArrayList();
		try {

			/*
				NAME: XUS KEY CHECK                     TAG: OWNSKEY
				  ROUTINE: XUSRB                        RETURN VALUE TYPE: ARRAY
				  AVAILABILITY: PUBLIC
				 DESCRIPTION:
				 This API will check if the user (DUZ) holds a security key or an array of
				 keys.
				 If a single security KEY is sent the result is returned in R(0).
				 If an array is sent down then the return array has the same order as the
				 calling array.
				INPUT PARAMETER: KEY                    PARAMETER TYPE: LIST
				  MAXIMUM DATA LENGTH: 30               REQUIRED: YES
				 DESCRIPTION:
				 If key is a single value it holds the one key to check.
				 If key is an array then the result is an array that matches the key
				 list with values that match the status of the key check for each key.
				 The return is a 1 if the user has the key and 0 if not.
				 */

			//String rpcName = "XUS KEY CHECK";
			// XUS ALLKEYS this rpc call uses to get all security keys from M system
			String rpcName = "XUS ALLKEYS";
			RpcRequest vReq = RpcRequestFactory.getRpcRequest();
			vReq.setUseProprietaryMessageFormat(true);
			vReq.setRpcContext(LoginController.LOGIN_RPC_CONTEXT);
			vReq.setRpcClientTimeOut(600);
			vReq.setRpcName(rpcName);

			//vReq.getParams().setParam(1, "array", appRoleList);

			RpcResponse vResp = myConnection.executeRPC(vReq);
			String results = vResp.getResults();
			if (LOGGER.isEnabledFor(Level.DEBUG)) {
				LOGGER.debug("results of XUS KEY CHECK: " + results);
			}

			StringTokenizer st = new StringTokenizer(results, "\n");
			String keyname = "";
			
			while (st.hasMoreTokens()) {
				keyname = st.nextToken();
				userRoleListFromM.add(keyname);
					if (LOGGER.isEnabledFor(Level.DEBUG)) {
						StringBuffer sb = new StringBuffer("Adding role '");
						sb.append(keyname);
						sb.append("' to role cache for username '");
						sb.append(username);
						sb.append("'.");
						LOGGER.debug(sb.toString());
					}
				}
		} catch (FoundationsException e) {

			if (LOGGER.isEnabledFor(Level.ERROR)) {
				LOGGER.error("Could not retrieve roles.");
			}
			throw new KaajeeException(e);
		}
/*
		//4. Store current roles for this username in database cache
		if (userRoleListFromM.size() > 0) {
			roleDAO.insertRoles(username, userRoleListFromM, LoginControllerUtils.getTimestamp());
		}

		if (LOGGER.isEnabledFor(Level.DEBUG)) {
			LOGGER.debug("returning from RoleUtils.cacheRoles");
		}
		*/
		//	5.store the current roles for this username in groupmembers
			  int i = 0;
			  while(i< userRoleListFromM.size())
			  {
 			    LoginControllerUtils.addMemberToGroup(username,userRoleListFromM.get(i).toString());
				if (LOGGER.isEnabledFor(Level.DEBUG)) {
					  StringBuffer sb = new StringBuffer("Adding group '");
					  sb.append(((String) userRoleListFromM.get(i)));
					  sb.append("' roles for this username in groupmembers'");
					  sb.append(username);
					  sb.append("'.");
					sb.append(userRoleListFromM.get(i).toString());
					  LOGGER.debug(sb.toString());
				  }
				  i = i+ 1;
			  }
	}
}
