class VulnerabilityRepository implements Constants {

	public List<Map<String, Object>> getDistributionSummaryByVulnType(String assetGroup, String severity)
			throws DataException {

		List<Map<String, Object>> distributionList = new ArrayList<>();
		long totalVulnCount = 0;
		Map<String, Object> infoOS = new HashMap<>();
		infoOS.put("category", "OS");
		infoOS.put(TOTAL_VULN_ASSETS, 0);
		infoOS.put(VULNEREBILITIES, 0);
		infoOS.put(UNIQUE_VULN_COUNT, 0);

		Map<String, Object> infoApp = new HashMap<>();
		infoApp.put("category", "Application");
		infoApp.put(TOTAL_VULN_ASSETS, 0);
		infoApp.put(VULNEREBILITIES, 0);
		infoApp.put(UNIQUE_VULN_COUNT, 0);

		StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup);
		urlToQuery.append("/").append(SEARCH);
		StringBuilder requestBody = new StringBuilder(
				"{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},").append(
						"{\"has_child\":{\"type\":\"vulninfo\",\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"terms\":{\"severitylevel.keyword\":[%s]}}]}}}}]}},")
						.append("\"aggs\":{\"vulninfo\":{\"children\":{\"type\":\"vulninfo\"},\"aggs\":{\"sev-filter\":{\"filter\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"terms\":{\"severitylevel.keyword\":[%s]}}]}},")
						.append("\"aggs\":{\"classification\":{\"terms\":{\"field\":\"classification.keyword\",\"size\":10},\"aggs\":{\"resources\":{\"cardinality\":{\"field\":\"_resourceid.keyword\",\"precision_threshold\":40000}}}}}}}}}}");

		String requestJson = String.format(requestBody.toString(), severity, severity);
		String responseJson = "";
		try {
			responseJson = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestJson);
		} catch (Exception e) {
			LOGGER.error("Error in getVulnerabilitySummaryByClassification from ES", e);
			throw new DataException(e);
		}

		JsonParser jsonParser = new JsonParser();
		JsonObject resultJson = (JsonObject) jsonParser.parse(responseJson);
		JsonObject aggsJson = (JsonObject) jsonParser.parse(resultJson.get(AGGREGATIONS).toString());
		JsonArray buckets = aggsJson.getAsJsonObject(VULN_INFO).getAsJsonObject("sev-filter")
				.getAsJsonObject("classification").getAsJsonArray(BUCKETS);
		if (buckets.size() > 0) {
			for (int i = 0; i < buckets.size(); i++) {
				totalVulnCount += buckets.get(i).getAsJsonObject().get(DOC_COUNT).getAsLong();
				if (buckets.get(i).getAsJsonObject().get("key").toString().replace("\"", "").equals("OS")) {
					infoOS.put(TOTAL_VULN_ASSETS,
							buckets.get(i).getAsJsonObject().get("resources").getAsJsonObject().get(VALUE).getAsLong());
					infoOS.put(VULNEREBILITIES, buckets.get(i).getAsJsonObject().get(DOC_COUNT).getAsLong());
				} else {
					infoApp.put(TOTAL_VULN_ASSETS,
							buckets.get(i).getAsJsonObject().get("resources").getAsJsonObject().get(VALUE).getAsLong());
					infoApp.put(VULNEREBILITIES, buckets.get(i).getAsJsonObject().get(DOC_COUNT).getAsLong());
				}
			}
		}

		requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},")
				.append("{\"has_child\":{\"type\":\"vulninfo\",\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"terms\":{\"severitylevel.keyword\":[%s]}}]}}}}]}},")
				.append("\"aggs\":{\"vulninfo\":{\"children\":{\"type\":\"vulninfo\"},\"aggs\":{\"sev-filter\":{\"filter\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"terms\":{\"severitylevel.keyword\":[%s]}}]}},")
				.append("\"aggs\":{\"classification\":{\"terms\":{\"field\":\"classification.keyword\",\"size\":10},\"aggs\":{\"unique-qid\":{\"cardinality\":{\"script\":\"doc['qid.keyword'].toString().replace('.0','')\",\"precision_threshold\":40000}}}}}}}}}}");

		requestJson = String.format(requestBody.toString(), severity, severity);
		responseJson = "";
		try {
			responseJson = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestJson);
		} catch (Exception e) {
			LOGGER.error(Constants.ERROR_UNIQUEHOST, e);
			throw new DataException(e);
		}

		resultJson = (JsonObject) jsonParser.parse(responseJson);
		aggsJson = (JsonObject) jsonParser.parse(resultJson.get(AGGREGATIONS).toString());
		buckets = aggsJson.getAsJsonObject(VULN_INFO).getAsJsonObject("sev-filter").getAsJsonObject("classification")
				.getAsJsonArray(BUCKETS);
		if (buckets.size() > 0) {
			for (int i = 0; i < buckets.size(); i++) {
				if (buckets.get(i).getAsJsonObject().get("key").toString().replace("\"", "").equals("OS")) {
					infoOS.put(UNIQUE_VULN_COUNT,
							buckets.get(i).getAsJsonObject().get(UNIQUE_QID).getAsJsonObject().get(VALUE).getAsLong());
				} else {
					infoApp.put(UNIQUE_VULN_COUNT,
							buckets.get(i).getAsJsonObject().get(UNIQUE_QID).getAsJsonObject().get(VALUE).getAsLong());
				}
			}
		}

		if (totalVulnCount > 0) {
			distributionList.add(infoOS);
			distributionList.add(infoApp);
		}
		double contribution = HUNDRED;
		for (int i = 0; i < distributionList.size(); i++) {
			Map<String, Object> info = distributionList.get(i);
			if (totalVulnCount > 0) {
				double contributionPercent = Math
						.floor((Double.valueOf(info.get(VULNEREBILITIES).toString()) / totalVulnCount) * HUNDRED);
				if (i == distributionList.size() - 1) {
					info.put("contribution", contribution);
				} else {
					info.put("contribution", contributionPercent);
					contribution = contribution - contributionPercent;
				}
			}
		}
		return distributionList;
	}

}