class AssetGroupStatsCollector implements Constants {

    public List<Map<String, String>> collectAssetGroupStats() {

        
        log.info("Start Collecting asset group stats");
        String token;
        try {
            token = getToken();
        } catch (Exception e1) {
            log.error("collectAssetGroupStats failed as unable to authenticate " , e1);
            Map<String,String> errorMap = new HashMap<>();
            errorMap.put(ERROR, "Exception in collectAssetGroupStats. Authorisation failed");
            errorMap.put(ERROR_TYPE,FATAL);
            errorMap.put(EXCEPTION, e1.getMessage());
            errorList.add(errorMap);
            return errorList;
        }
        Map<String, List<String>> assetGroupMap;
        try {
            assetGroupMap = AssetGroupUtil.fetchAssetGroups(ASSET_API_URL,token);
        } catch (Exception e1) {
            log.error("collectAssetGroupStats failed as unable to fetch asset groups " , e1);
            Map<String,String> errorMap = new HashMap<>();
            errorMap.put(ERROR, "Exception in fetchAssetGroups");
            errorMap.put(ERROR_TYPE, ERROR);
            errorMap.put(EXCEPTION, e1.getMessage());
            errorList.add(errorMap);
            return errorList;
        }

        ESManager.createIndex(AG_STATS, errorList);
        ESManager.createType(AG_STATS, "count_type", errorList);
        ESManager.createType(AG_STATS, "issuecompliance", errorList);
        ESManager.createType(AG_STATS, "compliance", errorList);
        ESManager.createType(AG_STATS, "tagcompliance", errorList);
        ESManager.createType(AG_STATS, "issues", errorList);
        if(VULN_API_URL!=null)
        	ESManager.createType(AG_STATS, "vulncompliance", errorList);


        List<String> assetGroups = new ArrayList<>(assetGroupMap.keySet());
        
        ExecutorService executor = Executors.newCachedThreadPool();

        executor.execute(() -> {
            try {
                uploadAssetGroupCountStats(assetGroups);
            } catch (Exception e) {
                log.error("Exception in uploadAssetGroupCountStats " , e);
                Map<String,String> errorMap = new HashMap<>();
                errorMap.put(ERROR, "Exception in uploadAssetGroupCountStats");
                errorMap.put(ERROR_TYPE, WARN);
                errorMap.put(EXCEPTION, e.getMessage());
                synchronized(errorList){
                    errorList.add(errorMap);
                }
            }
        });

     

        executor.execute(() -> {
            try {
                uploadAssetGroupRuleCompliance(assetGroupMap);
            } catch (Exception e) {
                log.error("Exception in uploadAssetGroupRuleCompliance " ,e);
                Map<String,String> errorMap = new HashMap<>();
                errorMap.put(ERROR, "Exception in uploadAssetGroupRuleCompliance");
                errorMap.put(ERROR_TYPE, WARN);
                errorMap.put(EXCEPTION, e.getMessage());
                synchronized(errorList){
                    errorList.add(errorMap);
                }
            }
        });
        executor.execute(() -> {
            try {
                uploadAssetGroupCompliance(assetGroupMap);
            } catch (Exception e) {
                log.error("Exception in uploadAssetGroupCompliance " , e);
                Map<String,String> errorMap = new HashMap<>();
                errorMap.put(ERROR, "Exception in uploadAssetGroupCompliance");
                errorMap.put(ERROR_TYPE, WARN);
                errorMap.put(EXCEPTION, e.getMessage());
                synchronized(errorList){
                    errorList.add(errorMap);
                }
            }
        });



 

        executor.execute(() -> {
            try {
                uploadAssetGroupTagCompliance(assetGroups);
            } catch (Exception e) {
                log.error("Exception in uploadAssetGroupTagCompliance" , e);
                Map<String,String> errorMap = new HashMap<>();
                errorMap.put(ERROR, "Exception in uploadAssetGroupTagCompliance");
                errorMap.put(ERROR_TYPE, WARN);
                errorMap.put(EXCEPTION, e.getMessage());
                synchronized(errorList){
                    errorList.add(errorMap);
                }
            }
        });

        executor.execute(() -> {
            try {
                uploadAssetGroupIssues(assetGroupMap);
            } catch (Exception e) {
                log.error("Exception in uploadAssetGroupIssues" , e);
                Map<String,String> errorMap = new HashMap<>();
                errorMap.put(ERROR, "Exception in uploadAssetGroupIssues");
                errorMap.put(ERROR_TYPE, WARN);
                errorMap.put(EXCEPTION, e.getMessage());
                synchronized(errorList){
                    errorList.add(errorMap);
                }
            }
        });
        
        if(VULN_API_URL!=null) {
	        executor.execute(() -> {
	            try {
	                uploadAssetGroupVulnCompliance(assetGroups);
	            } catch (Exception e) {
	                log.error("Exception in uploadAssetGroupVulnCompliance " , e);
	                Map<String,String> errorMap = new HashMap<>();
	                errorMap.put(ERROR, "Exception in uploadAssetGroupVulnCompliance");
	                errorMap.put(ERROR_TYPE, WARN);
	                errorMap.put(EXCEPTION, e.getMessage());
	                synchronized(errorList){
	                    errorList.add(errorMap);
	                }
	            }
	        });
        }
        



        executor.shutdown();
        while (!executor.isTerminated());

        log.info("End Collecting asset group stats");
        return errorList;
    }

}