class InventoryUtil {

	public static Map<String,List<LoadBalancerVH>> fetchElbInfo(BasicSessionCredentials temporaryCredentials, String skipRegions,String accountId,String accountName){
		com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancing elbClient ;
		Map<String,List<LoadBalancerVH>> elbMap = new LinkedHashMap<>();
		String expPrefix = InventoryConstants.ERROR_PREFIX_CODE+accountId + "\",\"Message\": \"Exception in fetching info for resource in specific region\" ,\"type\": \"Application ELB\" , \"region\":\"" ;
		for(Region region : RegionUtils.getRegions()){
			try{
				if(!skipRegions.contains(region.getName())){
					elbClient = com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancingClientBuilder.standard().
						 	withCredentials(new AWSStaticCredentialsProvider(temporaryCredentials)).withRegion(region.getName()).build();
					String nextMarker = null;
					DescribeLoadBalancersResult descElbRslt ;
					List<LoadBalancer> elbList = new ArrayList<>();
					do{
						descElbRslt = elbClient.describeLoadBalancers(new com.amazonaws.services.elasticloadbalancingv2.model.DescribeLoadBalancersRequest().withMarker(nextMarker));
						elbList.addAll(descElbRslt.getLoadBalancers());
						nextMarker = descElbRslt.getNextMarker();
					}while(nextMarker!=null);

					if(! elbList.isEmpty() ) {
						List<LoadBalancerVH> elbListTemp = new ArrayList<>();
						List<String> elbArns = elbList.stream().map(LoadBalancer::getLoadBalancerArn).collect(Collectors.toList());
						List<com.amazonaws.services.elasticloadbalancingv2.model.TagDescription> tagDescriptions = new ArrayList<>();
						int i = 0;
						List<String> elbArnsTemp  = new ArrayList<>();
						for(String elbArn : elbArns){
							i++;
							elbArnsTemp.add(elbArn);
							if(i%20 == 0){
								tagDescriptions.addAll(elbClient.describeTags(new com.amazonaws.services.elasticloadbalancingv2.model.DescribeTagsRequest().withResourceArns(elbArnsTemp)).getTagDescriptions());
								elbArnsTemp  = new ArrayList<>();
							}

						}
						if(!elbArnsTemp.isEmpty())
							tagDescriptions.addAll(elbClient.describeTags(new com.amazonaws.services.elasticloadbalancingv2.model.DescribeTagsRequest().withResourceArns(elbArnsTemp)).getTagDescriptions());

						elbList.parallelStream().forEach(elb->	{
							List<List<com.amazonaws.services.elasticloadbalancingv2.model.Tag>> tagsInfo =  tagDescriptions.stream().filter(tag -> tag.getResourceArn().equals( elb.getLoadBalancerArn())).map(x-> x.getTags()).collect(Collectors.toList());
							List<com.amazonaws.services.elasticloadbalancingv2.model.Tag> tags = new ArrayList<>();
							//****** Changes For Federated Rules Start ******
							String name = elb.getLoadBalancerArn();
							String accessLogBucketName = "";
							boolean accessLog = false;
						if (name != null) {
							com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancing appElbClient = com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancingClientBuilder
									.standard()
									.withCredentials(new AWSStaticCredentialsProvider(temporaryCredentials))
									.withRegion(region.getName()).build();
							com.amazonaws.services.elasticloadbalancingv2.model.DescribeLoadBalancerAttributesRequest request1 = new com.amazonaws.services.elasticloadbalancingv2.model.DescribeLoadBalancerAttributesRequest()
									.withLoadBalancerArn(name);
							List<LoadBalancerAttribute> listAccessLogBucketAttri = appElbClient
									.describeLoadBalancerAttributes(request1).getAttributes();
							for (LoadBalancerAttribute help : listAccessLogBucketAttri) {
								String attributeBucketKey = help.getKey();
								String attributeBucketValue = help.getValue();
								if (attributeBucketKey.equalsIgnoreCase("access_logs.s3.enabled")
										&& attributeBucketValue.equalsIgnoreCase("true")) {
									accessLog = true;
								}
								if ((attributeBucketKey.equalsIgnoreCase("access_logs.s3.bucket")
										&& attributeBucketValue != null)) {
									accessLogBucketName = attributeBucketValue;
								}
							}
							//****** Changes For Federated Rules End ******
							if(!tagsInfo.isEmpty())
								tags = tagsInfo.get(0);
							LoadBalancerVH elbTemp = new LoadBalancerVH(elb, tags, accessLogBucketName, accessLog);
							synchronized(elbListTemp){
								elbListTemp.add(elbTemp);
							}
						 }
						});

						log.debug(InventoryConstants.ACCOUNT + accountId +" Type : Application ELB " +region.getName() + " >> "+elbListTemp.size());
						elbMap.put(accountId+delimiter+accountName+delimiter+region.getName(),elbListTemp);
					}
				}
			}catch(Exception e){
				log.warn(expPrefix+ region.getName()+InventoryConstants.ERROR_CAUSE +e.getMessage()+"\"}");
				ErrorManageUtil.uploadError(accountId,region.getName(),"appelb",e.getMessage());
			}
		}
		return elbMap;
	}

	private  InventoryUtil();

}