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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;

import gov.va.med.fw.batchprocess.DataProcessExecutionContext;
import gov.va.med.fw.batchprocess.ExceptionWriterProcessCompletedHandler;

public class IVMDataSynchronizationProducerProcessCompletedHandler extends
        ExceptionWriterProcessCompletedHandler {
    private static String DATE_FORMAT = "yyyyMMddHHmmss";
    private static final String EXCEPTIONFILENAMESUFFIXDATA = "exceptionfilenamesuffixdata";
    
    protected Object getExceptionFileNameSuffixData(DataProcessExecutionContext context) {
        
        DataSynchronizationProducerStatistics stats = 
                (DataSynchronizationProducerStatistics) context.getContextData().get(AbstractDataSynchronizationProducerProcess.CONTEXT_FILE_STATS);
        
        //out file is not started yet. 
        if ( stats == null )
        {
            return new Date();
        }
        String inputFileName = stats.getFileName();
        // remove the date from it and use it       
        // file naming convention: UPD_DM_20081216142324.TXT
        String root = new StringTokenizer(inputFileName, ".").nextToken(); 
        StringTokenizer st = new StringTokenizer(root, "_");
        String date = null;
        while(st.hasMoreTokens()) 
            date = st.nextToken(); // get last token
        
        // make sure fully formed
        date = StringUtils.rightPad(date, DATE_FORMAT.length(), '0');
        
        SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
        
        try {
            return format.parse(date);
        } catch(ParseException e) {
            throw new IllegalArgumentException("File name [" + inputFileName + "] does not contain a date that is parsable to " +
                    DATE_FORMAT);
        }
    }
    
    // override dataProcessingComplete to allow append instead of writing to the exception data file
    public void dataProcessingComplete(DataProcessExecutionContext context) {
        // append exception data instead of write
        appendExceptionData(context);
    }
    
    public void appendExceptionData(DataProcessExecutionContext context) {
        
        // not calling getInterestedExceptionData since we are no longer filtering that list
        List exceptionData = context.getExceptionData();

        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);
            }
            
            getFileWriter().appendData(currentExceptionData, exceptionFileNameSuffixData);      
        }
    }
}
