class ElasticSearchPublicAccessAutoFix extends BaseFix {

	@Override
	public FixResult executeFix(Map<String, String> issue, Map<String, Object> clientMap, Map<String, String> ruleParams) {
		afterAutoFixSg = null;
		String resourceId = issue.get("resourceDisplayId");
		String defaultCidrIp = ruleParams.get("defaultCidrIp");
		String cidrIp = ruleParams.get("cidrIp");
		String accessPolicies = null;
		String denyAccessPolicy = null;
		JsonArray statments = new JsonArray();
		Map<String, Object> ec2ClinetMap = null;
		List<SecurityGroup> securityGroupsDetails = null;
		AmazonEC2 ec2Client = null;
		String securityGroupId = null;
		Collection<IpPermission> ipPermissionsToBeAdded = null;
		Gson serializer = new GsonBuilder().create();
		try {
			UpdateElasticsearchDomainConfigRequest domainConfigRequest = new UpdateElasticsearchDomainConfigRequest();
			AWSElasticsearch awsElasticsearch = (AWSElasticsearch) clientMap.get("client");
			
			ElasticsearchDomainStatus domainStatus = PublicAccessAutoFix.getDomainStatusForEsResource(clientMap, resourceId);
			String endPoint = domainStatus.getEndpoint();
			if (!StringUtils.isEmpty(endPoint)) {
				accessPolicies = domainStatus.getAccessPolicies();
				JsonObject accessPoliciesJson = serializer.fromJson(accessPolicies, JsonObject.class);
				if (accessPoliciesJson.has("Statement")) {
					statments = accessPoliciesJson.get("Statement").getAsJsonArray();
					if (PublicAccessAutoFix.isEsHavingPublicAccess(statments,cidrIp)) {
						denyAccessPolicy = accessPolicies.replace("Allow", "Deny");
						
						domainConfigRequest.setAccessPolicies(denyAccessPolicy);
						domainConfigRequest.setDomainName(resourceId);
						awsElasticsearch.updateElasticsearchDomainConfig(domainConfigRequest);
						afterPolicyAutoFix = denyAccessPolicy;
					}
				}
			}else{
					ec2ClinetMap = PublicAccessAutoFix.getAWSClient("ec2", issue, CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME));
					List<String> securityGroupsTobeApplied = new ArrayList<>();
					VPCDerivedInfo vpcDerivedInfo = domainStatus.getVPCOptions();
					List<String> securityGroupNames = vpcDerivedInfo.getSecurityGroupIds();
					Set<String> securityGroupsSet = new HashSet<>(securityGroupNames);
					Set<String> alreadyCheckedSgSet = new HashSet<>();
					if (ec2ClinetMap != null) {
						ec2Client = (AmazonEC2) ec2ClinetMap.get("client");
						securityGroupsDetails = PublicAccessAutoFix.getExistingSecurityGroupDetails(securityGroupsSet, ec2Client);
					}
					String vpcid;
					Set<String> publiclyAccessible = new HashSet<>();
					boolean isSgApplied = false;

					for (SecurityGroup securityGroup : securityGroupsDetails) {
						ipPermissionsToBeAdded = new ArrayList<>();
						publiclyAccessible = new HashSet<>();
						vpcid = securityGroup.getVpcId();
						securityGroupId = securityGroup.getGroupId();
						PublicAccessAutoFix.nestedSecurityGroupDetails(securityGroupId, ipPermissionsToBeAdded, ec2Client, publiclyAccessible,alreadyCheckedSgSet,0);

						if (!publiclyAccessible.isEmpty()) {
							// copy the security group and remove in bound rules
							String createdSgId = PublicAccessAutoFix.createSecurityGroup(securityGroupId, vpcid,ec2Client, ipPermissionsToBeAdded,resourceId,defaultCidrIp,securityGroup.getIpPermissions());
							if(!StringUtils.isEmpty(createdSgId)){
							securityGroupsTobeApplied.add(createdSgId);
							}
						} else {
							securityGroupsTobeApplied.add(securityGroupId);
						}
					}
					if (!securityGroupsTobeApplied.isEmpty()) {
						isSgApplied = PublicAccessAutoFix.applySecurityGroupsToElacticSearch(awsElasticsearch, securityGroupsTobeApplied, resourceId, domainConfigRequest);
						afterAutoFixSg = securityGroupsTobeApplied.toString();
					}

					if (isSgApplied) {
						LOGGER.info("{} sg's successfully applied for the resource {}",securityGroupsTobeApplied,  resourceId);
					}
				
			}

		} catch (Exception e) {
			LOGGER.error("Error in elastic public access autofix",e);
			throw new RuntimeException(e.getMessage());
		}
		return new FixResult(PacmanSdkConstants.STATUS_SUCCESS_CODE,"the elasticsearch "+resourceId+" is now fixed");
	}

}