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

package gov.va.med.fw.batchprocess;

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

import gov.va.med.fw.service.AbstractComponent;

/**
 * Simple implementation of DataFileProcessCompletedHandler that can support file deletion or file renaming.
 * 
 * Created Feb 7, 2006 10:13:36 AM
 * 
 * @author DNS   BOHMEG
 */
public class SimpleDataFileProcessCompletedHandler extends AbstractComponent
		implements DataProcessCompletedHandler {
	private boolean allowFileDeletion = true;

	private boolean shouldRenameFile;

	private String renameInputFileRoot;

	private String renameInputFileExtension;

	/*
	 * (non-Javadoc)
	 * 
	 * @see gov.va.med.fw.batchprocess.DataFileProcessCompletedHandler#fileProcessingComplete(java.io.File)
	 */
	private final void fileProcessingComplete(File inputFile, List exceptionData) {
		if (inputFile != null){
			if (shouldDeleteFile(exceptionData)) {
				if (allowFileDeletion && !inputFile.delete())
					throw new IllegalStateException("Unable to delete input file: "
						+ inputFile.getName());
			} else if (shouldRenameFile(exceptionData)) {
				if (!renameFile(inputFile))
					throw new IllegalStateException("Unable to rename input file: "
							+ inputFile.getName());
			}
		}
	}

	protected boolean shouldDeleteFile(List exceptionData) {
		return exceptionData.isEmpty();
	}

	protected boolean shouldRenameFile(List exceptionData) {
		return shouldRenameFile;
	}

	protected boolean renameFile(File inputFile) {
		String inputFilePath = inputFile.getParent();
		StringBuffer inputFileNameRoot = new StringBuffer("");
		StringTokenizer st = new StringTokenizer(inputFile.getName(), ".");
		int tokenCount = st.countTokens();
		for (int i = 1; i < tokenCount; i++) {
			inputFileNameRoot.append(st.nextToken());
			if (i != (tokenCount - 1))
				inputFileNameRoot.append(".");
		}
		if (tokenCount == 1)
			inputFileNameRoot.append(inputFile.getName());

		String newFileName = null;
		if (renameInputFileRoot != null)
			newFileName = renameInputFileRoot + renameInputFileExtension;
		else
			newFileName = inputFileNameRoot.toString()
					+ renameInputFileExtension;
		File newFile = new File(inputFilePath + File.separator + newFileName);
		int i=1;
		while(newFile.exists()) {
			if(logger.isWarnEnabled())
				logger.warn("Can not rename file to " + newFile.getName() + " since it exists already.  Trying one up number extension");
			
			newFile = new File(inputFilePath + File.separator + newFileName + (i++));
		}
		boolean result = inputFile.renameTo(newFile);
		inputFile.setLastModified(new Date().getTime());
		return result;
	}
	

	/**
	 * @return Returns the renameInputFileExtension.
	 */
	public String getRenameInputFileExtension() {
		return renameInputFileExtension;
	}

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

	/**
	 * @return Returns the renameInputFileRoot.
	 */
	public String getRenameInputFileRoot() {
		return renameInputFileRoot;
	}

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

	public void afterPropertiesSet() {
		if (renameInputFileRoot != null || renameInputFileExtension != null)
			shouldRenameFile = true;
	}

	/**
	 * @return Returns the allowFileDeletion.
	 */
	public boolean isAllowFileDeletion() {
		return allowFileDeletion;
	}

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

	/* (non-Javadoc)
	 * @see gov.va.med.fw.batchprocess.DataProcessCompletedHandler#dataProcessingComplete(gov.va.med.fw.batchprocess.DataProcessExecutionContext)
	 */
	public void dataProcessingComplete(DataProcessExecutionContext context) {
		DataFileProcessExecutionContext ctxt = (DataFileProcessExecutionContext) context;
		fileProcessingComplete(ctxt.getCurrentFile(), ctxt.getExceptionData());
	}
}
