class VulnerabilityService implements Constants {

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

		List<Map<String, Object>> remediationList = new ArrayList<>();
		if (StringUtils.isBlank(severity)) {
			severity = SEVERITY_LEVELS;
		}

		List<Map<String, Object>> eolActions = vulnerabilityRepository
				.getDataFromPacmanRDS("SELECT matchingString,subAction FROM cf_RemediationCriteria WHERE "
						+ "action='Remove/Replace EOL Software'");
		List<Map<String, Object>> stopRemoveActions = vulnerabilityRepository
				.getDataFromPacmanRDS("SELECT matchingString,subAction FROM cf_RemediationCriteria WHERE "
						+ "action='Stop Service/Remove Software'");
		List<Map<String, Object>> swConfigChangeActions = vulnerabilityRepository
				.getDataFromPacmanRDS("SELECT matchingString,subAction FROM cf_RemediationCriteria WHERE "
						+ "action='Software Configuration Change'");
		List<Map<String, Object>> swUpdateActions = vulnerabilityRepository.getDataFromPacmanRDS(
				"SELECT matchingString,subAction FROM cf_RemediationCriteria WHERE " + "action='Software Update'");

		String softwareConfig = getAllMatchingString(swConfigChangeActions);
		String softwareUpdate = getAllMatchingString(swUpdateActions);

		Map<String, Object> osPatching = new HashMap<>();
		osPatching.put(ACTION, "OS Patching");
		osPatching.put(DESCRIPTION, "Apply the patches released by the operating system provider");
		osPatching.put(CONTRIBUTION, 0);
		Map<String, Object> eolSoftware = new HashMap<>();
		eolSoftware.put(ACTION, "Remove/Replace EOL Software");
		eolSoftware.put(CONTRIBUTION, 0);
		eolSoftware.put(DESCRIPTION, "Remove or replace below listed End of Life Software versions");
		Map<String, Object> noSolution = new HashMap<>();
		noSolution.put(ACTION, "No Solution Available");
		noSolution.put(CONTRIBUTION, 0);
		noSolution.put(DESCRIPTION, "Vulnerabilities with no published solution yet");
		Map<String, Object> stopRemove = new HashMap<>();
		stopRemove.put(ACTION, "Stop Service/Remove Software");
		stopRemove.put(CONTRIBUTION, 0);
		stopRemove.put(DESCRIPTION, "Stop unimportant vulnerable services, remove malicious softwares from the hosts");
		Map<String, Object> swConfigChange = new HashMap<>();
		swConfigChange.put(ACTION, "Software Configuration Change");
		swConfigChange.put(CONTRIBUTION, 0);
		swConfigChange.put(DESCRIPTION,
				"Fix the configurations of the below listed softwares. Some default configurations like default admin username and password should be replaced with a stronger one");
		Map<String, Object> swUpdate = new HashMap<>();
		swUpdate.put(ACTION, "Software Update");
		swUpdate.put(CONTRIBUTION, 0);
		swUpdate.put(DESCRIPTION,
				"Update the below listed softwares to their latest version or apply patches released by the software provider ");

		List<Map<String, Object>> eolSubActions = new ArrayList<>();
		List<Map<String, Object>> stopRemoveSubActions = new ArrayList<>();
		List<Map<String, Object>> swConfigChangeSubActions = new ArrayList<>();
		List<Map<String, Object>> swUpdateSubActions = new ArrayList<>();

		Map<String, Object> unclassified = new HashMap<>();
		unclassified.put(ACTION, "Unclassified");
		unclassified.put(DESCRIPTION,
				"These vulnerabilities are not classified yet. Refer the vulnerability description to fix the vulnerability");
		unclassified.put(CONTRIBUTION, 0);

		Map<String, Object> qids = vulnerabilityRepository.getAllQidByAG(assetGroup, severity);
		Long total = qids.entrySet().stream().mapToLong(entry -> Long.valueOf(entry.getValue().toString())).sum();
		for (String qidTitleClass : qids.keySet()) {
			String qid = qidTitleClass.split("~")[0];
			String vulnTitle = qidTitleClass.split("~")[1].toLowerCase();
			String classification = qidTitleClass.split("~")[2];
			if ("OS".equalsIgnoreCase(classification)) {
				osPatching.put(CONTRIBUTION, Long.valueOf(osPatching.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
			} else if (vulnTitle.contains("EOL/Obsolete".toLowerCase())) {
				eolSoftware.put(CONTRIBUTION, Long.valueOf(eolSoftware.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
				formSubActionList(eolActions, eolSubActions, vulnTitle,
						Long.valueOf(qids.get(qidTitleClass).toString()));
			} else if ("11925".equals(qid) || "370914".equals(qid)) {
				noSolution.put(CONTRIBUTION, Long.valueOf(noSolution.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
			} else if (vulnTitle.contains("Java Debug Wire Protocol".toLowerCase())) {
				stopRemove.put(CONTRIBUTION, Long.valueOf(stopRemove.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
				formSubActionList(stopRemoveActions, stopRemoveSubActions, vulnTitle,
						Long.valueOf(qids.get(qidTitleClass).toString()));
			} else if (checkVulnTitle(vulnTitle, softwareConfig)) {
				swConfigChange.put(CONTRIBUTION, Long.valueOf(swConfigChange.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
				formSubActionList(swConfigChangeActions, swConfigChangeSubActions, vulnTitle,
						Long.valueOf(qids.get(qidTitleClass).toString()));
			} else if (checkVulnTitle(vulnTitle, softwareUpdate)) {
				swUpdate.put(CONTRIBUTION, Long.valueOf(swUpdate.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
				formSubActionList(swUpdateActions, swUpdateSubActions, vulnTitle,
						Long.valueOf(qids.get(qidTitleClass).toString()));
			} else {
				unclassified.put(CONTRIBUTION, Long.valueOf(unclassified.get(CONTRIBUTION).toString())
						+ Long.valueOf(qids.get(qidTitleClass).toString()));
			}
		}

		calculateContributionPercentage(eolSubActions, Long.valueOf(eolSoftware.get(CONTRIBUTION).toString()));
		calculateContributionPercentage(stopRemoveSubActions, Long.valueOf(stopRemove.get(CONTRIBUTION).toString()));
		calculateContributionPercentage(swConfigChangeSubActions,
				Long.valueOf(swConfigChange.get(CONTRIBUTION).toString()));
		calculateContributionPercentage(swUpdateSubActions, Long.valueOf(swUpdate.get(CONTRIBUTION).toString()));

		eolSoftware.put(SUB_ACTIONS, eolSubActions);
		stopRemove.put(SUB_ACTIONS, stopRemoveSubActions);
		swConfigChange.put(SUB_ACTIONS, swConfigChangeSubActions);
		swUpdate.put(SUB_ACTIONS, swUpdateSubActions);

		remediationList.add(osPatching);
		remediationList.add(eolSoftware);
		remediationList.add(noSolution);
		remediationList.add(stopRemove);
		remediationList.add(swConfigChange);
		remediationList.add(swUpdate);
		remediationList.add(unclassified);

		calculateContributionPercentage(remediationList, total);
		return remediationList;
	}

}