/********************************************************************
 * Copyright © 2006 VHA. All rights reserved
 ********************************************************************/


package gov.va.med.fw.batchprocess;

import gov.va.med.fw.io.writer.FormattedFileWriter;
import gov.va.med.fw.service.AbstractComponent;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.Validate;

/**
 * DataProcessCompletedHandler implementation that writes exception data to a file.
 * 
 * Created Mar 15, 2006 10:52:53 AM
 * @author DNS   BOHMEG
 */
public class ExceptionWriterProcessCompletedHandler extends AbstractComponent
		implements DataProcessCompletedHandler {

	private FormattedFileWriter fileWriter;
	private boolean deleteInputFile = true;
    private static final String EXCEPTIONFILENAMESUFFIXDATA = "exceptionfilenamesuffixdata";

	/* (non-Javadoc)
	 * @see gov.va.med.fw.batchprocess.DataProcessCompletedHandler#dataProcessingComplete(gov.va.med.fw.batchprocess.DataProcessExecutionContext)
	 */
	public void dataProcessingComplete(DataProcessExecutionContext context) {
		// write exception data
		writeExceptionData(context);
		//Fix for CR_7600 If the batchProcess is interrupted do not delete the files.
		if(!context.isInterrupted()){
		    // delete input file (if any)
		    if(context instanceof DataFileProcessExecutionContext) {
			    File inputFile = ((DataFileProcessExecutionContext) context).getCurrentFile();
			    if (deleteInputFile && !inputFile.delete())
				    throw new IllegalStateException("Unable to delete input file: "+ inputFile.getName());			
		    }
		}
	}
	
	protected final void writeExceptionData(DataProcessExecutionContext context) {
		List exceptionData = getInterestedExceptionData(context);
		if(exceptionData != null && !exceptionData.isEmpty())
			fileWriter.writeData(exceptionData, getExceptionFileNameSuffixData(context));		
	}
	
	public void appendExceptionData(DataProcessExecutionContext context) {

		List exceptionData = getInterestedExceptionData(context);

		if (exceptionData != null && !exceptionData.isEmpty()) {
			// copy the list to another one for writing
			List currentExceptionData = new ArrayList(exceptionData);
			// lock the exception list within the context and remove data list
			synchronized (exceptionData) {
				exceptionData.clear();
			}

           Object exceptionFileNameSuffixData = context.getContextData().get(EXCEPTIONFILENAMESUFFIXDATA);
            if ( exceptionFileNameSuffixData == null )
            {
                exceptionFileNameSuffixData = getExceptionFileNameSuffixData(context);
                context.getContextData().put(EXCEPTIONFILENAMESUFFIXDATA, exceptionFileNameSuffixData);
            }
	            
			fileWriter.appendData(currentExceptionData, exceptionFileNameSuffixData);
		}
	}

	// subclasses can override for subset of exception data to write to file
	protected List getInterestedExceptionData(DataProcessExecutionContext context) {
		return context.getExceptionData();
	}

	// subclasses can override
	protected Object getExceptionFileNameSuffixData(DataProcessExecutionContext context) {
		Date executionStartDate = 
			context.getProcessStatistics().getProcessingStartDate();
		return executionStartDate;
	}

	/**
	 * @return Returns the fileWriter.
	 */
	public FormattedFileWriter getFileWriter() {
		return fileWriter;
	}

	/**
	 * @param fileWriter The fileWriter to set.
	 */
	public void setFileWriter(FormattedFileWriter fileWriter) {
		this.fileWriter = fileWriter;
	}
	
	public void afterPropertiesSet() {
		Validate.notNull(fileWriter);
	}

	/**
	 * @return Returns the deleteInputFile.
	 */
	public boolean isDeleteInputFile() {
		return deleteInputFile;
	}

	/**
	 * @param deleteInputFile The deleteInputFile to set.
	 */
	public void setDeleteInputFile(boolean deleteInputFile) {
		this.deleteInputFile = deleteInputFile;
	}
}
