package gov.va.med.mpn.codedcontrol.impl;

import gov.va.med.mpn.codedcontrol.CodedControl;
import gov.va.med.mpn.codedcontrol.model.UserResponse;
import gov.va.med.mpn.dao.interfaces.CategoryDAO;
import gov.va.med.mpn.dao.interfaces.ClassificationDAO;
import gov.va.med.mpn.dao.interfaces.CodedControlDataDAO;
import gov.va.med.mpn.entity.pojo.Category;
import gov.va.med.mpn.entity.pojo.Classification;
import gov.va.med.mpn.entity.pojo.CodedControlData;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.PathParam;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * The Class CodedControlService. Implementation class for all coded control
 * service calls.
 *
 * <p>
 * <A HREF="http://www.hp.com"> Hewlett-Packard Enterprise Services</A>
 * </p>
 *
 * @author <a href="mailto:pratap.chilukuri@hp.com">Pratap Chilukuri</a>
 */
@Service("codedcontrolservice")
public class CodedControlService implements CodedControl {

	/** The slf4j logger. */
	private final Logger slf4jLogger = LoggerFactory
			.getLogger(CodedControlService.class);

	@Autowired
	ClassificationDAO classificationDao;

	@Autowired
	CodedControlDataDAO codedControlDataDAO;

	@Autowired
	CategoryDAO categoryDAO;

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * gov.va.med.mpn.codedcontrol.CodedControl#fetchControl(java.lang.String)
	 */
	public UserResponse fetchControl(String path) {

		slf4jLogger.info("fetchControl - Start");
		UserResponse response = new UserResponse();

		List<CodedControlData> codedControlList = new ArrayList<CodedControlData>();

		Map<String, String> params = parsePath(path);
		String name = params.get("name");
		String classSearch = params.get("class");
		String categorySearch = params.get("category");

		// Checking if all the selection criteria for
		// controlName/Classification/Category .
		if ((StringUtils.isEmpty(name)) && (StringUtils.isEmpty(classSearch))
				&& (StringUtils.isEmpty(categorySearch))) {// 000
			slf4jLogger.info("fetchControl - all criteria empty");
			response.setMessage("No criteria selected, please select Control Name / Category / Classification.");
			response.setSuccess(false);

		} else if ((StringUtils.isEmpty(name))
				&& (StringUtils.isEmpty(classSearch))
				&& (StringUtils.isNotEmpty(categorySearch))) {// 001
			slf4jLogger
					.info("fetchControl - Control Name empty - Classification empty - Category:"
							+ categorySearch);
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithCategoryId(Integer
							.valueOf(categorySearch));
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}

		} else if ((StringUtils.isEmpty(name))
				&& (StringUtils.isNotEmpty(classSearch))
				&& (StringUtils.isNotEmpty(categorySearch))) {// 011
			slf4jLogger
					.info("fetchControl - Control Name empty - Classification:"
							+ classSearch + "- Category:" + categorySearch);
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithClassificationIdAndCategoryId(
							Integer.valueOf(classSearch),
							Integer.valueOf(categorySearch));
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}

		} else if ((StringUtils.isNotEmpty(name))
				&& (StringUtils.isNotEmpty(classSearch))
				&& (StringUtils.isNotEmpty(categorySearch))) {// 111
			slf4jLogger.info("fetchControl - Control Name:" + name
					+ "- Classification:" + classSearch + "- Category:"
					+ categorySearch);
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithClassificationIdAndCategoryIdAndName(
							Integer.valueOf(classSearch),
							Integer.valueOf(categorySearch), name);
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}
		} else if ((StringUtils.isNotEmpty(name))
				&& (StringUtils.isNotEmpty(classSearch))
				&& (StringUtils.isEmpty(categorySearch))) {// 110
			slf4jLogger.info("fetchControl - Control Name:" + name
					+ "- Classification:" + classSearch + "- Category Empty");
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithClassificationIdAndName(
							Integer.valueOf(classSearch), name);
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}
		} else if ((StringUtils.isNotEmpty(name))
				&& (StringUtils.isEmpty(classSearch))
				&& (StringUtils.isEmpty(categorySearch))) {// 100
			slf4jLogger.info("fetchControl - Control Name:" + name
					+ "- Classification Empty - Category Empty");
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithControlName(name);
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}
		} else if ((StringUtils.isNotEmpty(name))
				&& (StringUtils.isEmpty(classSearch))
				&& (StringUtils.isNotEmpty(categorySearch))) {// 101
			slf4jLogger.info("fetchControl - Control Name:" + name
					+ "- Classification Empty - Category:" + categorySearch);
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithCategoryIdAndName(
							Integer.valueOf(categorySearch), name);
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}
		} else if ((StringUtils.isEmpty(name))
				&& (StringUtils.isNotEmpty(classSearch))
				&& (StringUtils.isEmpty(categorySearch))) {// 010
			slf4jLogger
					.info("fetchControl - Control Name Empty- Classification:"
							+ classSearch + "- Category Empty");
			codedControlList = codedControlDataDAO
					.findCodedControlDataWithClassId(Integer
							.valueOf(classSearch));
			if (codedControlList.size() == 0) {
				response.setMessage("No Data Found for selected criteria");
				response.setSuccess(false);
			} else {
				response.setCodedControls(codedControlList);
			}
		}

		slf4jLogger.info("fetchControl - End");
		return response;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * gov.va.med.mpn.codedcontrol.CodedControl#fetchControlByUuid(java.lang
	 * .String)
	 */
	public UserResponse fetchControlByUuid(String uuid) {
		slf4jLogger.info("fetchControlByUuid - Start");
		UserResponse response = new UserResponse();

		List<CodedControlData> codedControlList = new ArrayList<CodedControlData>();
		HashMap<String, Object> qryParams = new HashMap<String, Object>();
		qryParams.put("uuid", uuid);
		codedControlList = codedControlDataDAO.findByNamedQueryAndNamedParam(
				"codedcontroldata.findRowWithUUID", qryParams);

		if (codedControlList.isEmpty()) {
			response.setMessage("No Coded Control found with UUID: " + uuid);
			response.setSuccess(false);
		} else {
			response.setCodedControls(codedControlList);
		}

		slf4jLogger.info("fetchControlByUuid - End");
		return response;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see gov.va.med.mpn.codedcontrol.CodedControl#fetchCategories()
	 */
	public UserResponse fetchCategories() {

		UserResponse response = new UserResponse();

		List<Category> categoryList = categoryDAO.findAllCategoriesSorted();

		if (categoryList.size() > 0) {

			List<CodedControlData> controlList = new ArrayList<CodedControlData>();
			for (Category category : categoryList) {
				CodedControlData codedControlData = new CodedControlData();
				codedControlData.setCategory(category);
				controlList.add(codedControlData);
			}
			response.setCodedControls(controlList);
		} else {
			response.setMessage("No Data Found");
			response.setSuccess(false);
		}

		return response;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see gov.va.med.mpn.codedcontrol.CodedControl#fetchClasses()
	 */
	public UserResponse fetchClasses() {

		UserResponse response = new UserResponse();

		List<Classification> classificationList = classificationDao
				.findAllClassesSorted();

		if (classificationList.size() > 0) {

			List<CodedControlData> controlList = new ArrayList<CodedControlData>();
			for (gov.va.med.mpn.entity.pojo.Classification classification : classificationList) {
				CodedControlData codedControlData = new CodedControlData();
				codedControlData.setClassification(classification);
				controlList.add(codedControlData);
			}

			response.setCodedControls(controlList);
		} else {
			response.setMessage("No Data Found");
			response.setSuccess(false);
		}

		return response;
	}

	/**
	 * Parses the path.
	 *
	 * @param path
	 *            the path
	 * @return the map
	 */
	private Map<String, String> parsePath(String path) {
		if (path.startsWith("/")) {
			path = path.substring(1);
		}
		String[] pathParts = path.split("/");
		Map<String, String> pathMap = new HashMap<String, String>();
		for (int pathCounter = 0; pathCounter < pathParts.length / 2; pathCounter++) {
			String key = pathParts[2 * pathCounter];
			String value = pathParts[2 * pathCounter + 1];
			pathMap.put(key, value);
		}
		return pathMap;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * gov.va.med.mpn.codedcontrol.CodedControl#createControl(gov.va.med.mpn
	 * .codedcontrol.model.Control)
	 */
// PNCSSF-1528 This method commented out, pending implementing access control for this service.
//	public UserResponse createControl(CodedControlData codedControl) {
//
//		UserResponse response = new UserResponse();
//
//		codedControlDataDAO.persist(codedControl);
//
//		return response;
//	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * gov.va.med.mpn.codedcontrol.CodedControl#updateControl(gov.va.med.mpn
	 * .codedcontrol.model.Control)
	 */
// PNCSSF-1528 This method commented out, pending implementing access control for this service.
//	public UserResponse updateControl(CodedControlData codedControl) {
//
//		UserResponse response = new UserResponse();
//
//		CodedControlData codedControlData = codedControlDataDAO
//				.merge(codedControl);
//		List<CodedControlData> controlList = new ArrayList<CodedControlData>();
//		controlList.add(codedControlData);
//		response.setCodedControls(controlList);
//
//		return response;
//	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * gov.va.med.mpn.codedcontrol.CodedControl#deleteControl(java.lang.String)
	 */
// PNCSSF-1528 This method commented out, pending implementing access control for this service.
//	public UserResponse deleteControl(final @PathParam("id") String id) {
//
//		UserResponse response = new UserResponse();
//
//		CodedControlData codedControlData = codedControlDataDAO
//				.findAllWithUUID(id);
//		if (codedControlData != null) {
//			codedControlDataDAO.remove(codedControlData);
//		} else {
//			response.setMessage("No Coded Control found to delete");
//			response.setSuccess(false);
//		}
//
//		return response;
//	}

}