package gov.va.med.esr.common.batchprocess;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import gov.va.med.fw.batchprocess.DataFileProcessStatistics;

/**
 * @author DNS   KATIKM
 * Keeps track of statistics for VSSC data file process
 */
public class LoadVSSCDataProcessStatistics extends DataFileProcessStatistics {

	private static final long serialVersionUID = -5619317047208428159L;
	
	private int numberOfRecordsRead = 0;
	private int numberOfRecordsRejected = 0;
	private int numberOfRecordsAccepted = 0;
	private int numberOfOEFRecordsFiled = 0;
	private int numberOfOIFRecordsFiled = 0;
	private int numberOfUnknwonLocationRecordsFiled = 0;
	private int numberOfUnspecifiedLocationRecordsFiled = 0;
	
	private int numberOfRecordsNotMatched = 0;
	private int numberOfInvalidRecords = 0;
	private int numberOfInconsistentRecords = 0;
	private int numberOfRecordsNotFiled = 0;  //failed in rules
			
	public LoadVSSCDataProcessStatistics () {}		
	
	public int getNumberOfRecordsAccepted() {
		return this.numberOfRecordsAccepted;
	}
	public int getNumberOfRecordsRead() {
		return this.numberOfRecordsRead;
	}
	public int getNumberOfRecordsRejected() {
		return this.numberOfRecordsRejected;
	}
	public void setNumberOfRecordsAccepted(int numberOfRecordsAccepted) {
		this.numberOfRecordsAccepted = numberOfRecordsAccepted;
	}
	public void setNumberOfRecordsRead(int numberOfRecordsRead) {
		this.numberOfRecordsRead = numberOfRecordsRead;
	}
	public void setNumberOfRecordsRejected(int numberOfRecordsRejected) {
		this.numberOfRecordsRejected = numberOfRecordsRejected;
	}
	public int getNumberOfInconsistentRecords() {
		return this.numberOfInconsistentRecords;
	}
	public int getNumberOfInvalidRecords() {
		return this.numberOfInvalidRecords;
	}
	public int getNumberOfOEFRecordsFiled() {
		return this.numberOfOEFRecordsFiled;
	}
	public int getNumberOfOIFRecordsFiled() {
		return this.numberOfOIFRecordsFiled;
	}
	public int getNumberOfRecordsNotFiled() {
		return this.numberOfRecordsNotFiled;
	}
	public int getNumberOfRecordsNotMatched() {
		return this.numberOfRecordsNotMatched;
	}
	public int getNumberOfUnknwonLocationRecordsFiled() {
		return this.numberOfUnknwonLocationRecordsFiled;
	}
	public int getNumberOfUnspecifiedLocationRecordsFiled() {
		return this.numberOfUnspecifiedLocationRecordsFiled;
	}
	public void setNumberOfInconsistentRecords(int numberOfInconsistentRecords) {
		this.numberOfInconsistentRecords = numberOfInconsistentRecords;
	}
	public void setNumberOfInvalidRecords(int numberOfInvalidRecords) {
		this.numberOfInvalidRecords = numberOfInvalidRecords;
	}
	public void setNumberOfOEFRecordsFiled(int numberOfOEFRecordsFiled) {
		this.numberOfOEFRecordsFiled = numberOfOEFRecordsFiled;
	}
	public void setNumberOfOIFRecordsFiled(int numberOfOIFRecordsFiled) {
		this.numberOfOIFRecordsFiled = numberOfOIFRecordsFiled;
	}
	public void setNumberOfRecordsNotFiled(int numberOfRecordsNotFiled) {
		this.numberOfRecordsNotFiled = numberOfRecordsNotFiled;
	}
	public void setNumberOfRecordsNotMatched(int numberOfRecordsNotMatched) {
		this.numberOfRecordsNotMatched = numberOfRecordsNotMatched;
	}
	public void setNumberOfUnknwonLocationRecordsFiled(
			int numberOfUnknwonLocationRecordsFiled) {
		this.numberOfUnknwonLocationRecordsFiled = numberOfUnknwonLocationRecordsFiled;
	}
	public void setNumberOfUnspecifiedLocationRecordsFiled(
			int numberOfUnspecifiedLocationRecordsFiled) {
		this.numberOfUnspecifiedLocationRecordsFiled = numberOfUnspecifiedLocationRecordsFiled;
	}
	
	public String toString() {
		ToStringBuilder builder = new ToStringBuilder(this,
				ToStringStyle.MULTI_LINE_STYLE);

		this.buildToString(builder);

		return builder.toString();
	}
	
	protected void buildToString(ToStringBuilder builder) {
		//Summary information
		builder.append(getProcessName());
		builder.append("Processing Start Date",getProcessingStartDate());
		builder.append("Processing End Date",getProcessingEndDate());
		builder.append("Total Records Processed",getNumberOfRecordsRead());		
		//success records
		builder.append("Total Records Filed",
				getPercent(getNumberOfRecordsRead(),getNumberOfRecordsAccepted()));		
		//failed records
		builder.append("Total Records Not Filed",
				getPercent(getNumberOfRecordsRead(),getNumberOfRecordsRejected()));
		
		builder.append("Breakdown of successfull records by location");
		//Successfully processed record statistic
		builder.append("OEF",
				getPercent(getNumberOfRecordsRead(),getNumberOfOEFRecordsFiled()));
		builder.append("OIF",
				getPercent(getNumberOfRecordsRead(),getNumberOfOIFRecordsFiled()));
		builder.append("Unknown OEF/OIF",
				getPercent(getNumberOfRecordsRead(),getNumberOfUnknwonLocationRecordsFiled()));
		builder.append("Conflict Unspecified",
				getPercent(getNumberOfRecordsRead(),getNumberOfUnspecifiedLocationRecordsFiled()));
		builder.append("Breakdown of failed records by reason");
		
		//Failed Records Statistics
		builder.append("Records Not Matched",
				getPercent(getNumberOfRecordsRead(),getNumberOfRecordsNotMatched()));
		builder.append("Invalid Records",
				getPercent(getNumberOfRecordsRead(),getNumberOfInvalidRecords()));
		builder.append("Inconsistent Records",
				getPercent(getNumberOfRecordsRead(),getNumberOfInconsistentRecords()));
		builder.append("Records that could not be filed",
				getPercent(getNumberOfRecordsRead(),getNumberOfRecordsNotFiled()));
				
		//File Statistics
		builder.append("Total files processed",getProcessedFiles().size());
	    builder.append("Directory Path", getProcessedFilePath());
		builder.append("Processed Files", getProcessedFiles());
	}
	
	public void updateStatistics(LoadVSSCDataResult result)
	{
		//summary

		setNumberOfRecordsRead(getNumberOfRecordsRead() + 
				result.getTotalAccepted() + result.getTotalRejected());
		setNumberOfRecordsRejected(getNumberOfRecordsRejected() + result.getTotalRejected());
		setNumberOfRecordsAccepted(getNumberOfRecordsAccepted() + result.getTotalAccepted());
		
		//details of accepted (filed records)
		setNumberOfOEFRecordsFiled(getNumberOfOEFRecordsFiled() + result.getCountOEFAccepted());
		setNumberOfOIFRecordsFiled(getNumberOfOIFRecordsFiled() + result.getCountOIFAccepted());
		setNumberOfUnknwonLocationRecordsFiled(getNumberOfUnknwonLocationRecordsFiled() + result.getCountUnknownAccepted());
		setNumberOfUnspecifiedLocationRecordsFiled(getNumberOfUnspecifiedLocationRecordsFiled() + result.getCountUnspecifiedAccepted());
		
		//details of failed records
		setNumberOfInvalidRecords(getNumberOfInvalidRecords() + result.getCountMissingInvalidRejected());
		setNumberOfInconsistentRecords(getNumberOfInconsistentRecords() + result.getCountCCRejected());
		setNumberOfRecordsNotMatched(getNumberOfRecordsNotMatched() + result.getCountNoMatchRejected());
		setNumberOfRecordsNotFiled(getNumberOfRecordsNotFiled() + result.getTotalNotFiled());
	}
	
	private String getPercent(int total, int processed){
		
		String out = String.valueOf(processed);		
		if (total > 0 ) {
			out = out  + " ( " + String.valueOf(Math.round(100*processed/total)) + "% )";
		}
		return out;
	}
}
