/*
 * Created on Sep 17, 2004
 * 
 */
package gov.va.med.esr.common.batchprocess;

import java.util.Hashtable;
import java.util.Date;

import gov.va.med.fw.model.AbstractKeyedEntity;

import gov.va.med.esr.common.model.comms.AacLetterRequest;
import gov.va.med.esr.common.model.comms.CommsLogEntry;
import gov.va.med.esr.common.model.comms.HecRejectReason;
import gov.va.med.esr.common.model.lookup.ComLetterTemplateType;

/**
 * @author DNS   TSAIG
 * 
 * CommsExportStatistics collects all the statistics required by [UC15] Manage
 * Bulk Mailing [1218]: 5146[UC15.8] Capture Statistics The system captures
 * statistics for the entire batch file that is sent to the AAC. These
 * statistics will be included in a mail bulletin that will be sent to the
 * appropriate HEC staff. The statistics captured are: Date/Time File Created
 * (Start Time of Process) Number of Files Number of Communications Number
 * Rejected Form Number Communications Per Form Rejections per Reason per Form
 * 
 * File Name, Records Per File
 * 
 */
public class CommsExportStatistics extends AbstractKeyedEntity {
	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 5284593107794163278L;
	

	public static String LINE_BREAK = "\n";

	private static String APPEND_TEXT = " to be send to AAC = ";
	
	private static String CMS_APPEND_TEXT = " to be send to CMS = ";	

	private static String APPEND_HB_TEXT = " to be send to HANDBOOK CMS = ";
	
	private Hashtable countPerFormTable = new Hashtable();

	private Hashtable rejectPerReasonPerformTable = new Hashtable();

	private String fileName = null;

	private String originalFileName = null;
	
	private Date startTime;

	private Date endTime;

	private int numberSent;

	private int numberRejected;

	private int numberCancelled;
	
	private int numberRemailed;
    
    private int numberWithException;



    public CommsExportStatistics() {
		super();
	}
    
	public synchronized void addToCountPerFormTable(String formNumber) {

		if (countPerFormTable.get(formNumber) == null) {
			// new form number, set initial count
			countPerFormTable.put(formNumber, new Integer(1));
		}
		else {
			// existing form, increment the count
			countPerFormTable.put(formNumber, new Integer(
					((Integer) countPerFormTable.get(formNumber)).intValue() + 1));
		}
	}
    

	public void addToCountPerFormTable(AacLetterRequest entry) {
		if (entry == null)
			return;

		String formNumber = entry.getCommsTemplateFormNumber();
		if (countPerFormTable.get(formNumber) == null) {
			// new form number, set initial count
			countPerFormTable.put(formNumber, new Integer(1));
		}
		else {
			// existing form, increment the count
			countPerFormTable.put(formNumber, new Integer(
					((Integer) countPerFormTable.get(formNumber)).intValue() + 1));
		}
	}

	public String getCountPerFormTableText() {
		if (countPerFormTable == null || countPerFormTable.size() == 0)
			return "";

		StringBuffer txt = new StringBuffer();
		java.util.Enumeration keys = countPerFormTable.keys();

		while (keys.hasMoreElements()) {
			Object key = keys.nextElement();
			if (isIVMFinalLetter((String)key) || isCompassionLetter((String)key)) 
				txt.append(key).append(CMS_APPEND_TEXT).append(countPerFormTable.get(key))
				.append(LINE_BREAK);
			else
				txt.append(key).append(APPEND_TEXT).append(countPerFormTable.get(key))
				.append(LINE_BREAK);
		}

		return txt.toString();

	}

	public String getHbCountPerFormTableText() {
		if (countPerFormTable == null || countPerFormTable.size() == 0)
			return "";

		StringBuffer txt = new StringBuffer();
		java.util.Enumeration keys = countPerFormTable.keys();

		while (keys.hasMoreElements()) {
			Object key = keys.nextElement();
			txt.append(key).append(APPEND_HB_TEXT).append(countPerFormTable.get(key))
					.append(LINE_BREAK);
		}

		return txt.toString();

	}

	public synchronized void updateRejectPerReasonPerformTable(String errorText, String formNumber) {
		
		if (errorText == null || errorText.length() == 0)
		return;
		
		String[] errorReasons = errorText.split(LINE_BREAK);
		
		String reason = null;
		Hashtable formTab = null;
		for (int i = 0; i < errorReasons.length; i++) {
			reason = errorReasons[i];
			if (rejectPerReasonPerformTable.get(reason) == null) {
				// new reason, add
				formTab = new Hashtable();
				formTab.put(formNumber, new Integer(1));

				rejectPerReasonPerformTable.put(reason, formTab);

			}
			else {
				// existing reason, update
				formTab = (Hashtable) rejectPerReasonPerformTable.get(reason);
				if (formTab.get(formNumber) == null) {
					// new form under the reason
					formTab.put(formNumber, new Integer(1));
				}
				else {
					// existing form, increment the count
					formTab.put(formNumber, new Integer(((Integer) formTab
							.get(formNumber)).intValue() + 1));
				}
			}
		}
	}

	public void updateRejectPerReasonPerformTable(CommsLogEntry entry) {
		if (entry == null || entry.getHecRejectionReasons() == null
				|| entry.getHecRejectionReasons().size() == 0)
			return;

		String reasonDesc = null;
		String formNumber = entry.getFormNumber();
		Hashtable formTab = null;
		for (int i = 0; i < entry.getHecRejectionReasons().size(); i++) {
			reasonDesc = ((HecRejectReason) entry.getHecRejectionReasons().get(i))
					.getHecRejectReasonDescription();

			if (rejectPerReasonPerformTable.get(reasonDesc) == null) {
				// new reason, add
				formTab = new Hashtable();
				formTab.put(formNumber, new Integer(1));

				rejectPerReasonPerformTable.put(reasonDesc, formTab);

			}
			else {
				// existing reason, update
				formTab = (Hashtable) rejectPerReasonPerformTable.get(reasonDesc);
				if (formTab.get(formNumber) == null) {
					// new form under the reason
					formTab.put(formNumber, new Integer(1));
				}
				else {
					// existing form, increment the count
					formTab.put(formNumber, new Integer(((Integer) formTab
							.get(formNumber)).intValue() + 1));
				}
			}
		}
	}

	// / Get the rejected letters (fails exception) for an AAC batch, sorted by
	// form number
	// / </summary>
	// / Examples:
	// / Bad Demographics :
	// / 600C = 183
	// / 604A = 49
	// / 623A = 13
	// /
	// / Dup: multiple 300.12s :
	// / 600C = 104
	// / 604A = 169
	// / 604B = 3
	// / 623A = 3
	// /
	// / Duplicate SSN :
	// / 600C = 87
	// / 604A = 192
	// / 623A = 14
	// /
	// / Pseudo SSN :
	// / 600C = 90
	// / 604A = 6
	// / 623A = 1

	public String getRejectPerReasonPerFormText() {
		if (rejectPerReasonPerformTable == null
				|| rejectPerReasonPerformTable.size() == 0)
			return "";

		StringBuffer txt = new StringBuffer();
		java.util.Enumeration reasonKeys = rejectPerReasonPerformTable.keys();

		String reasonDesc = null;
		Hashtable formTab = null;
		String formNumber = null;

		while (reasonKeys.hasMoreElements()) {
			reasonDesc = (String) reasonKeys.nextElement();
			txt.append(LINE_BREAK).append(reasonDesc).append(" : ").append(
					LINE_BREAK);

			formTab = (Hashtable) rejectPerReasonPerformTable.get(reasonDesc);
			java.util.Enumeration formKeys = formTab.keys();

			while (formKeys.hasMoreElements()) {
				formNumber = (String) formKeys.nextElement();
				txt.append(formNumber).append(" = ").append(
						((Integer) formTab.get(formNumber)).toString()).append(
						LINE_BREAK);
			}

		}

		/*
		 * while (keys.hasMoreElements()) { Object key = keys.nextElement();
		 * txt.append(LINE_BREAK).append(FORM_NUMBER_TEXT).append(key).append(LINE_BREAK);
		 * 
		 * Hashtable tab = (Hashtable)rejectPerReasonPerformTable.get(key);
		 * java.util.Enumeration keys2 = tab.keys(); while
		 * (keys2.hasMoreElements()) { Object key2 = keys2.nextElement();
		 * txt.append(key2).append(": ").append(tab.get(key2)).append(LINE_BREAK); }
		 * txt.append(LINE_BREAK);
		 *  }
		 */return txt.toString();

	}

	/**
	 * @return Returns the countPerFormTable.
	 */
	public Hashtable getCountPerFormTable() {
		return countPerFormTable;
	}

	/**
	 * @param countPerFormTable The countPerFormTable to set.
	 */
	public void setCountPerFormTable(Hashtable countPerFormTable) {
		this.countPerFormTable = countPerFormTable;
	}

	/**
	 * @return Returns the endTime.
	 */
	public Date getEndTime() {
		return endTime;
	}

	/**
	 * @param endTime The endTime to set.
	 */
	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	/**
	 * @return Returns the fileName.
	 */
	public String getFileName() {
		return fileName;
	}

	/**
	 * @param fileName The fileName to set.
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * @return Returns the numberCancelled.
	 */
	public int getNumberCancelled() {
		return numberCancelled;
	}

	/**
	 * @param numberCancelled The numberCancelled to set.
	 */
	public void setNumberCancelled(int numberCancelled) {
		this.numberCancelled = numberCancelled;
	}

	/**
	 * @return Returns the numberRejected.
	 */
	public int getNumberRejected() {
		return numberRejected;
	}

	/**
	 * @param numberRejected The numberRejected to set.
	 */
	public void setNumberRejected(int numberRejected) {
		this.numberRejected = numberRejected;
	}
	
	public synchronized void incrementNumberRejected() {
		this.numberRejected++;
	}

	/**
	 * @return Returns the numberSent.
	 */
	public int getNumberSent() {
		return numberSent;
	}

	/**
	 * @param numberSent The numberSent to set.
	 */
	public void setNumberSent(int numberSent) {
		this.numberSent = numberSent;
	}

	public synchronized void incrementNumberSent() {
		this.numberSent++;
	}
	/**
	 * @return Returns the rejectPerReasonPerformTable.
	 */
	public Hashtable getRejectPerReasonPerFormTable() {
		return rejectPerReasonPerformTable;
	}

	/**
	 * @param rejectPerReasonPerformTable The rejectPerReasonPerformTable to set.
	 */
	public void setRejectPerReasonPerformTable(
			Hashtable rejectPerReasonPerformTable) {
		this.rejectPerReasonPerformTable = rejectPerReasonPerformTable;
	}

	/**
	 * @return Returns the startTime.
	 */
	public Date getStartTime() {
		return startTime;
	}

	/**
	 * @param startTime The startTime to set.
	 */
	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	/**
	 * @return Returns the numberRemailed.
	 */
	public int getNumberRemailed() {
		return numberRemailed;
	}

	/**
	 * @param numberRemailed The numberRemailed to set.
	 */
	public void setNumberRemailed(int numberRemailed) {
		this.numberRemailed = numberRemailed;
	}
    
    public int getNumberWithException() {
        return numberWithException;
    }

    public void setNumberWithException(int numberWithException) {
        this.numberWithException = numberWithException;
    }
    
	public synchronized void incrementNumberWithException() {
		this.numberWithException++;
	}
    
    public String getOriginalFileName() {
        return originalFileName;
    }

    public void setOriginalFileName(String originalFileName) {
        this.originalFileName = originalFileName;
    }
	private boolean isIVMFinalLetter(String form) {
		if (form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_400.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_450.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_451.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_452.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_453.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_454.getCode()) ||
				form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_455.getCode())) {
			return true;
		}
		return false;
	}
	private boolean isCompassionLetter(String form) {
		if (form.equalsIgnoreCase(ComLetterTemplateType.FORM_NUMBER_683A.getCode())) {
			return true;
		}
		return false;
	}    
}
