class VulnerabilityService implements Constants {

	@SuppressWarnings("unchecked")
	public Map<String, Integer> getHighestLowestPerformers(String assetGroup, String severity, String type) {

		String mngtLevel2 = "2";
		String mngtLevel3 = "3";
		String mngtLevel4 = "4";
		String mngtLevel5 = "5";
		String mngtLevel6 = "6";
		String mngtLevel7 = "7";

		Map<String, Long> appDetails = new HashMap<>();
		List<String> vulnTargetTypes = getVulnTargetTypes(assetGroup);

		if (StringUtils.isBlank(severity)) {
			severity = SEVERITY_LEVELS;
		}
		Map<String, Integer> perfData = new HashMap<>();

		if ("org".equalsIgnoreCase(type)) {
			if (!vulnTargetTypes.isEmpty()) {
				for (String parentType : vulnTargetTypes) {
					try {
						Map<String, Long> appDetailsTemp = vulnerabilityRepository.getAppsBySeverity(assetGroup,
								parentType, severity);
						if (appDetails.isEmpty()) {
							appDetails = new HashMap<>(appDetailsTemp);
						} else {
							for (Entry<String, Long> appDetailTemp : appDetailsTemp.entrySet()) {
								boolean appExists = false;
								for (Entry<String, Long> appDetail : appDetails.entrySet()) {
									if (appDetail.getKey().equals(appDetailTemp.getKey())) {
										appDetails.put(appDetail.getKey(),
												appDetail.getValue() + appDetailTemp.getValue());
										appExists = true;
										break;
									}
								}
								if (!appExists) {
									appDetails.put(appDetailTemp.getKey(), appDetailTemp.getValue());
								}
							}
						}
					} catch (Exception e) {
						logger.error("Exception in getHighestLowestPeformers org", e);
					}
				}
			}
			try {
				Map<String, Map<String, List<String>>> directorsInfo = getDirectorsForAG(appDetails.keySet());
				if (directorsInfo.get(mngtLevel2) != null && directorsInfo.get(mngtLevel2).size() > 1) {
					formPerformersData(appDetails, perfData, directorsInfo.get(mngtLevel2));
				} else if (directorsInfo.get(mngtLevel3) != null && directorsInfo.get(mngtLevel3).size() > 1) {
					formPerformersData(appDetails, perfData, directorsInfo.get(mngtLevel3));
				} else if (directorsInfo.get(mngtLevel4) != null && directorsInfo.get(mngtLevel4).size() > 1) {
					formPerformersData(appDetails, perfData, directorsInfo.get(mngtLevel4));
				} else {
					Map<String, List<String>> directorLevel5Above = new HashMap<>();
					if (directorsInfo.get(mngtLevel5) != null) {
						directorLevel5Above.putAll(directorsInfo.get(mngtLevel5));
					}
					if (directorsInfo.get(mngtLevel6) != null) {
						directorLevel5Above.putAll(directorsInfo.get(mngtLevel6));
					}
					if (directorsInfo.get(mngtLevel7) != null) {
						directorLevel5Above.putAll(directorsInfo.get(mngtLevel7));
					}
					formPerformersData(appDetails, perfData, directorLevel5Above);
				}
			} catch (Exception e) {
				logger.error("Exception in getHighestLowestPeformers org", e);
			}
		} else if (APPLICATION.equalsIgnoreCase(type)) {
			try {
				List<Map<String, Object>> vulnApplications = getVulnerabilityByAppAndEnv(assetGroup, TAGS_APPS, "");
				for (Map<String, Object> appInfo : vulnApplications) {
					String app = appInfo.get(APPS).toString();
					List<Map<String, Object>> sevInfo = (List<Map<String, Object>>) appInfo.get(SEV_INFO);
					perfData.put(app, getVulnInstanceCount(sevInfo, severity));
				}
			} catch (Exception e) {
				logger.error("Exception in getHighestLowestPeformers app", e);
			}

		} else if (ENVIRONMENT.equalsIgnoreCase(type)) {

			try {
				List<Map<String, Object>> vulnEnvmnts = getVulnerabilityByAppAndEnv(assetGroup, TAGS_ENV, "");
				for (Map<String, Object> envInfo : vulnEnvmnts) {
					String env = envInfo.get(ENV).toString();
					List<Map<String, Object>> sevInfo = (List<Map<String, Object>>) envInfo.get(SEV_INFO);
					perfData.put(env, getVulnInstanceCount(sevInfo, severity));
				}
			} catch (Exception e) {
				logger.error("Exception in getHighestLowestPeformers env", e);
			}
		}
		return perfData.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors
				.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
	}

}