package gov.va.med.esr.service.impl;

import java.math.BigDecimal;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.messaging.MsdsErrorLogEntry;
import gov.va.med.esr.common.model.messaging.MsdsMessageLogEntry;
import gov.va.med.esr.common.model.messaging.MsdsMessagePayloadEntry;
import gov.va.med.esr.common.persistent.messaging.MsdsErrorLogEntryDAO;
import gov.va.med.esr.common.persistent.messaging.MsdsMessageLogEntryDAO;
import gov.va.med.esr.common.persistent.messaging.MsdsMessagePayloadEntryDAO;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.UniqueIdentifierGenerator;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.esr.service.LogTransmissionService;

public class LogTransmissionServiceImpl extends AbstractComponent implements LogTransmissionService {
	
	private MsdsMessageLogEntryDAO msdsMessageLogEntryDAO = null;
	private MsdsMessagePayloadEntryDAO msdsMessagePayloadEntryDAO = null;
	private MsdsErrorLogEntryDAO   msdsErrorLogEntryDAO = null;
	private LookupService       lookupService          = null;
	private UniqueIdentifierGenerator generator = null;
	
	/**
     * An instance of serialVersionUID
     */
    private static final long   serialVersionUID       = 7440299997017245373L;
	/**
	    * A default constructor
	    */
	   public LogTransmissionServiceImpl() {
	      super();
	   }
	
	/**
     * @see gov.va.med.fw.service.AbstractComponent#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        Validate.notNull(this.msdsMessageLogEntryDAO, "A msdsMessageLogEntry DAO must be configured");       
        Validate.notNull(this.lookupService, "A lookup service must be configured");
    }
    
    /**
     * @param msdsMessageLogEntryDAO
     *            The msdsMessageLogEntryDAO to set.
     */
    public void setMsdsMessageLogEntryDAO(MsdsMessageLogEntryDAO msdsMessageLogEntryDAO) {
        this.msdsMessageLogEntryDAO = msdsMessageLogEntryDAO;
    }

    /**
     * @return The msdsMessageLogEntryDAO
     */
    protected MsdsMessageLogEntryDAO getMsdsMessageLogEntryDAO() {
    	return this.msdsMessageLogEntryDAO;
    }
    
    /**
     * @param msdsMessagePayloadEntryDAO
     *            The msdsMessagePayloadEntryDAO to set.
     */
    public void setMsdsMessagePayloadEntryDAO(MsdsMessagePayloadEntryDAO msdsMessagePayloadEntryDAO) {
        this.msdsMessagePayloadEntryDAO = msdsMessagePayloadEntryDAO;
    }

    /**
     * @return The msdsMessagePayloadEntryDAO
     */
    protected MsdsMessagePayloadEntryDAO getMsdsMessagePayloadEntryDAO() {
    	return this.msdsMessagePayloadEntryDAO;
    }
    
    /**
     * @param msdsMessageLogEntryDAO
     *            The msdsMessageLogEntryDAO to set.
     */
    public void setMsdsErrorLogEntryDAO(MsdsErrorLogEntryDAO msdsErrorLogEntryDAO) {
        this.msdsErrorLogEntryDAO = msdsErrorLogEntryDAO;
    }

    /**
     * @return The msdsMessageLogEntryDAO
     */
    protected MsdsErrorLogEntryDAO getMsdsErrorLogEntryDAO() {
    	return this.msdsErrorLogEntryDAO;
    }
    
    /**
     * @param lookupService
     *            The lookupService to set.
     */
    public void setLookupService(LookupService lookupService) {
        this.lookupService = lookupService;
    }

    /**
	 * @return Returns the lookupService.
	 */
	public LookupService getLookupService() {
		return lookupService;
	}
	
	/**
	    * @param generator
	    */
	public void setGenerator(UniqueIdentifierGenerator generator) {
       this.generator = generator;
   }
	   
   /**
    * @return a UniqueIdentifierGenerator
    */
   public UniqueIdentifierGenerator getGenerator() {
       return this.generator;
   }
	
	/**
	 * Implements method specified by MessagingService interface. (non-Javadoc)
	 *
	 * @see gov.va.med.esr.service.MessagingService#generateControlIdentifier()
	 */
   public String generateControlIdentifier() throws ServiceException {
      return this.generator.generate().toString();
   }
   
   /**
    * @see gov.va.med.esr.service.MessagingService#logMessage(gov.va.med.esr.common.model.messaging.MessageLogEntry)
    */
   public MsdsMessageLogEntry logMessage(MsdsMessageLogEntry entry) throws ServiceException {

      // Persist the message log entry
      try {
    	  MsdsMessageLogEntry cachedEntry = null; 
         if (entry.getEntityKey() == null) {
        	 EntityKey key = (EntityKey)msdsMessageLogEntryDAO.insertObject(entry);
        	 if (key != null) {
        		 cachedEntry = (MsdsMessageLogEntry)msdsMessageLogEntryDAO.getByKey(key);
        	 }
         }
         else {
        	 cachedEntry =
               (MsdsMessageLogEntry)msdsMessageLogEntryDAO.getByKey(entry.getEntityKey());
        	 
            msdsMessageLogEntryDAO.saveObject(cachedEntry);
            msdsMessageLogEntryDAO.flush();
         }
         return cachedEntry;
      }
      catch (Exception ex) { //Catch all exceptions than just DAOException
         throw new ServiceException("Failed to log message ", ex);
      }
   }
   
   /**
    * @see gov.va.med.esr.service.MessagingService#logMessage(gov.va.med.esr.common.model.messaging.MessageLogEntry)
    */
   public void logMessagePayload(MsdsMessageLogEntry entry, String request, String response) throws ServiceException {

      // Persist the message log entry
      try {
          
        if (logger.isDebugEnabled()) {
        	logger.debug("LogTransmissionServiceImpl logMessagePayload : entry: " + entry );
	    }    	  
         if (entry != null && entry.getEntityKey() != null) {
        	 
             if (logger.isDebugEnabled()) {
             	logger.debug("LogTransmissionServiceImpl logMessagePayload : entry.getEntityKey(): " + entry.getEntityKey() );
     	    }         	 
        	 MsdsMessagePayloadEntry cachedEntry =
                 (MsdsMessagePayloadEntry)msdsMessagePayloadEntryDAO.find(entry);
             if (logger.isDebugEnabled()) {
             	logger.debug("LogTransmissionServiceImpl logMessagePayload : cachedEntry found by entry: " + cachedEntry );
     	    }  
        	 if (cachedEntry == null) {
        		 cachedEntry = new MsdsMessagePayloadEntry();
        		 cachedEntry.setMsdsMessageLogId((BigDecimal)entry.getEntityKey().getKeyValue());
                 if (logger.isDebugEnabled()) {
                  	logger.debug("LogTransmissionServiceImpl logMessagePayload : new cachedEntry: " + cachedEntry );
          	    }         		 
        	 } 
        	 
        	 if (request != null) {        		 
        		 cachedEntry.setRequest(request);
        	 }
        	 
        	 if (response != null) {        		 
        		 cachedEntry.setResponse(response);
        	 }        	 

        	 msdsMessagePayloadEntryDAO.saveObject(cachedEntry);
        	 msdsMessagePayloadEntryDAO.flush();
         }
      }
      catch (Exception ex) { //Catch all exceptions than just DAOException
         throw new ServiceException("Failed to log message payload ", ex);
      }
   }
   
   public void logMessage(MsdsErrorLogEntry error) throws ServiceException {

	      // Persist the message log entry
	      try {
	          
	         if (error.getEntityKey() == null) {
	            msdsErrorLogEntryDAO.saveObject(error);
	         }
	         else {
	        	 MsdsMessageLogEntry cachedEntry =
	               (MsdsMessageLogEntry)msdsErrorLogEntryDAO.getByKey(error.getEntityKey());
	        	 
	        	 msdsErrorLogEntryDAO.saveObject(cachedEntry);
	         }
	         
	         
	         
	      }
	      catch (DAOException ex) {
	         throw new ServiceException("Failed to log message ", ex);
	      }
	   }

   /**
    * @see gov.va.med.esr.service.MessagingService#getMessageLogEntryById(java.math.BigDecimal)
    */
   public MsdsMessageLogEntry getMessageLogEntryById( BigDecimal id)
      throws ServiceException {
      
      MsdsMessageLogEntry mle = null;
      try {
         mle = msdsMessageLogEntryDAO.getById( id );
      } 
      catch( DAOException e ) {
         
         throw new ServiceException("Failed to get message log entry by id " + id, e);
      }
      return mle;
   }
   
   public MsdsMessageLogEntry getMessageLogEntry(BigDecimal id)
			throws ServiceException {

		MsdsMessageLogEntry mle = null;
		try {
			mle = msdsMessageLogEntryDAO.getByControlId(id);
		} catch (DAOException e) {

			throw new ServiceException("Failed to get message log entry by id "
					+ id, e);
		}
		return mle;
}
   
   public boolean findCountCompletion(EntityKey personId) throws ServiceException {
       
       try {
          Integer count = getMsdsMessageLogEntryDAO().findCompleteCount(personId);
          if (count.intValue() > 2){
              return true;
          }
          return false;
       } 
       catch (DAOException e) {
          throw new ServiceException( "Failed to Retrieve the Site that last trsmitted the Message",e );
       }
    }
   
   public MsdsMessageLogEntry getClockEntry(EntityKey personId)
			throws ServiceException {

		MsdsMessageLogEntry mle = null;
		try {
			mle = getMsdsMessageLogEntryDAO().findClockSetEntry(personId);
		} catch (DAOException e) {

			throw new ServiceException("Failed to get message log entry by id "
					+ personId, e);
		}
		return mle;
}

	   
	

}
