class RecommendationsController {

    @SuppressWarnings("unchecked")
	@PostMapping(value = "/v1/recommendations")
    public ResponseEntity<Object> getRecommendations(@RequestBody(required = true) Request request) {
		
		Map<String, String> filter = request.getFilter();
		if (filter == null) {
            filter = new HashMap<>();
        }
		
		List<String> acceptedFilterKeys = Arrays.asList(AssetConstants.FILTER_APPLICATION,AssetConstants.FILTER_CATEGORY,AssetConstants.FILTER_GENERAL);
        for (Map.Entry<String, String> entry : filter.entrySet()) {
            if (!acceptedFilterKeys.contains(entry.getKey())) {
                return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FILTER_ACCEPTS
                        + StringUtils.join(acceptedFilterKeys, ", ")));
            }
        }
        
        if (!filter.containsKey(AssetConstants.FILTER_CATEGORY)) {
            return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_CATEGORY+" is mandatory in filter"));
        }
		
		if(!filter.containsKey(AssetConstants.FILTER_GENERAL)) {
			return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_GENERAL+" is mandatory in filter"));
		}
		
		String general = filter.get(AssetConstants.FILTER_GENERAL);
		String assetGroup = request.getAg();
		if (general.equals(AssetConstants.FALSE) && StringUtils.isBlank(assetGroup)) {
            return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY));
        }

        int from = request.getFrom();
        int size = request.getSize();
        if (from < 0) {
            return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_NEGATIVE));
        }

        String searchText = request.getSearchtext();
        String category = filter.get(AssetConstants.FILTER_CATEGORY);
        String application = filter.get(AssetConstants.FILTER_APPLICATION);
        
		Map<String, Object> recommendations;
		try {
			recommendations = recommendationsService.getRecommendations(assetGroup, category, application, general);
		} catch (DataException e) {
			LOGGER.error("Error in getRecommendations "+ e);
			return ResponseUtils.buildFailureResponse(e);
		}
		List<Map<String, Object>> masterList = (List<Map<String, Object>>) recommendations.get("response");
		List<Map<String, Object>> masterDetailList = (List<Map<String, Object>>) CommonUtils
                .filterMatchingCollectionElements(masterList, searchText, true);
		
		if(masterDetailList.isEmpty()) {
			recommendations.put("response", new ArrayList<>());
	        recommendations.put("total", 0);
			
	        return ResponseUtils.buildSucessResponse(recommendations);
		}
		
		if (from >= masterDetailList.size()) {
	        return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_EXCEEDS));
	    }
		
        int endIndex = 0;

        if (size == 0) {
            size = masterDetailList.size();
        }

        if ((from + size) > masterDetailList.size()) {
            endIndex = masterDetailList.size();
        } else {
            endIndex = from + size;
        }

        List<Map<String, Object>> subDetailList = masterDetailList.subList(from, endIndex);
        recommendations.put("response", subDetailList);
        recommendations.put("total", masterDetailList.size());
		
        return ResponseUtils.buildSucessResponse(recommendations);
    }

}