class RecommendationsRepository {

	public Map<String,Object> getRecommendations(String assetGroup, String category, String application) throws DataException {
		
		Map<String,Object> result = new HashMap<>();
		List<Map<String,Object>> recommendations = new ArrayList<>();
		Double totalMonthlySavings = 0.0;
		
		StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(Constants.SEARCH);
		StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"_entity.keyword\":true}}");
		if(StringUtils.isNotBlank(application)) {
			requestBody.append(",{\"match\":{\"tags.Application.keyword\":\"");
			requestBody.append(application);
			requestBody.append("\"}}");
		}
		requestBody.append("]}},\"aggs\":{\"type\":{\"terms\":{\"field\":\"_entitytype.keyword\",\"size\":100000},"
				+ "\"aggs\":{\"recommendations\":{\"children\":{\"type\":\"recommendation\"},\"aggs\":{\"latest\":{\"filter\":{\"match\":{\"latest\":true}},\"aggs\":{\"category\":{\"filter\":{\"match\":{\"category.keyword\":\"");
		requestBody.append(category);
		requestBody.append("\"}},\"aggs\":{\"recommendation\":{\"terms\":{\"field\":\"recommendationId.keyword\",\"size\":10000},"
				+ "\"aggs\":{\"savings\":{\"sum\":{\"field\":\"monthlysavings\"}}}}}}}}}}}}}}");
		String responseDetails;
		try {
			responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString());
		} catch (Exception e) {
			LOGGER.error("Error in getRecommendations "+e);
			throw new DataException(e);
		}
        JsonParser parser = new JsonParser();
        JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject();
        JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject();
        JsonArray typeBuckets = aggregations.get("type").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray();
        if (typeBuckets.size() > 0) {
            for (int i=0; i<typeBuckets.size();i++) {
            	JsonObject typeObj = (JsonObject) typeBuckets.get(i);
                if (typeObj != null) {
                	JsonObject recommendationsObj = typeObj.get("recommendations").getAsJsonObject();
            		if(recommendationsObj.has("latest") && recommendationsObj.get("latest").getAsJsonObject().has("category")) {
            			JsonObject categoryObj = recommendationsObj.get("latest").getAsJsonObject().get("category").getAsJsonObject();
            			JsonArray recommendationBuckets =  categoryObj.get("recommendation").getAsJsonObject().getAsJsonArray(Constants.BUCKETS);
            			if(recommendationBuckets.size() > 0) {
            				for (int j=0; j<recommendationBuckets.size();j++) {
            					JsonObject recommendationObj = (JsonObject) recommendationBuckets.get(j);
            					String recommendationId = recommendationObj.get(Constants.KEY).getAsString();
            					Map<String,Object> recommendationInfo = getRecommendation(recommendationId);
            					if(!recommendationInfo.isEmpty()) {
            						Map<String,Object> recommendation = new HashMap<>();
                					recommendation.put("recommendationId", recommendationId);
                					recommendation.put("recommendation", recommendationInfo.get("checkname"));
                					recommendation.put("description", recommendationInfo.get("checkdescription").toString().replace("[NL]", "<br />"));
                					recommendation.put("total", typeObj.get(Constants.DOC_COUNT).getAsLong());
                					recommendation.put("recommended", recommendationObj.get(Constants.DOC_COUNT).getAsLong());
                					recommendation.put("targetType", typeObj.get(Constants.KEY).getAsString());
                					if("cost_optimizing".equals(category)) {
	                					Double monthlySavings = recommendationObj.get("savings").getAsJsonObject().get(Constants.VALUE).getAsDouble();
	                            		totalMonthlySavings += monthlySavings;
	                					recommendation.put("monthlySavings", Math.round(monthlySavings));
                					}
                					recommendations.add(recommendation);
            					}
            				}
            			}
            		}
                }
            }
        }
		
		result.put("ag", assetGroup);
		result.put("category", category);
		if("cost_optimizing".equals(category)) {
			result.put("totalMonthlySavings", Math.round(totalMonthlySavings));
		}
		result.put("response", recommendations);
		return result;
	}

}