class ServiceAccountPrivilegesRule extends BaseRule {

	@Override
	public RuleResult execute(final Map<String, String> ruleParam, Map<String, String> resourceAttributes) {
		logger.debug("========ServiceAccountPrivilegesRule started=========");
		Map<String, String> ruleParamIam = new HashMap<>();
		ruleParamIam.putAll(ruleParam);
		ruleParamIam.put(PacmanRuleConstants.REGION, Regions.DEFAULT_REGION.getName());

		Map<String, Object> map = null;
		Annotation annotation = null;
		AmazonIdentityManagementClient identityManagementClient = null;

		String roleIdentifyingString = ruleParam.get(PacmanSdkConstants.Role_IDENTIFYING_STRING);
		String userName = resourceAttributes.get(PacmanRuleConstants.IAM_USER_NAME);
		String unApprovedIamActions = ruleParam.get(PacmanRuleConstants.UNAPPROVED_IAM_ACTIONS);
		String tagsSplitter = ruleParam.get(PacmanSdkConstants.SPLITTER_CHAR);

		String severity = ruleParam.get(PacmanRuleConstants.SEVERITY);
		String category = ruleParam.get(PacmanRuleConstants.CATEGORY);

		MDC.put(PacmanSdkConstants.EXECUTION_ID, ruleParam.get(PacmanSdkConstants.EXECUTION_ID));
		MDC.put(PacmanSdkConstants.RULE_ID, ruleParam.get(PacmanSdkConstants.RULE_ID));

		List<LinkedHashMap<String, Object>> issueList = new ArrayList<>();
		LinkedHashMap<String, Object> issue = new LinkedHashMap<>();

		List<String> unApprovedPrivileges = new ArrayList<>();

		if (!PacmanUtils.doesAllHaveValue(severity, category, roleIdentifyingString, unApprovedIamActions,
				tagsSplitter)) {
			logger.info(PacmanRuleConstants.MISSING_CONFIGURATION);
			throw new InvalidInputException(PacmanRuleConstants.MISSING_CONFIGURATION);
		}

		try {
			map = getClientFor(AWSService.IAM, roleIdentifyingString, ruleParamIam);
			identityManagementClient = (AmazonIdentityManagementClient) map.get(PacmanSdkConstants.CLIENT);
			List<String> priviligesList = PacmanUtils.splitStringToAList(unApprovedIamActions, tagsSplitter);
			if (userName.startsWith(PacmanRuleConstants.SERVICE_ACCOUNTS)) {
				Set<String> actionSet = IAMUtils.getAllowedActionsByUserPolicy(identityManagementClient, userName);
				if (!actionSet.isEmpty()) {
					for (String privilege : priviligesList) {
						if (actionSet.contains(privilege)) {
							unApprovedPrivileges.add(privilege);
						}
					}
					if (!unApprovedPrivileges.isEmpty()) {
						annotation = Annotation.buildAnnotation(ruleParam, Annotation.Type.ISSUE);
						annotation.put(PacmanSdkConstants.DESCRIPTION, "IAM service account has unapproved privileges");
						annotation.put(PacmanRuleConstants.SEVERITY, severity);
						annotation.put(PacmanRuleConstants.CATEGORY, category);
						annotation.put(PacmanRuleConstants.IAM_USER_NAME, userName);
						issue.put(PacmanRuleConstants.VIOLATION_REASON,
								"IAM service account has this action privileges");
						issue.put("unapprovedPrivileges", String.join(",", unApprovedPrivileges));
						issueList.add(issue);
						annotation.put("issueDetails", issueList.toString());

						logger.debug("========ServiceAccountPrivilegesRule ended with annotation {} :=========",
								annotation);
						return new RuleResult(PacmanSdkConstants.STATUS_FAILURE, PacmanRuleConstants.FAILURE_MESSAGE,
								annotation);
					}
				}
			} else {
				logger.info(userName, " : is not a service account");
			}

		} catch (UnableToCreateClientException e) {
			logger.error(PacmanRuleConstants.UNABLE_TO_GET_CLIENT, e);
			throw new InvalidInputException(PacmanRuleConstants.UNABLE_TO_GET_CLIENT, e);
		}
		logger.debug("========ServiceAccountPrivilegesRule ended=========");
		return new RuleResult(PacmanSdkConstants.STATUS_SUCCESS, PacmanRuleConstants.SUCCESS_MESSAGE);
	}

}