/*                          
 * mBench: The Open Source Micro Benchmark Tool 
 *                                             
 * Distributable under GPL license. 
 * See terms of license at gnu.org.                 
 *
 * Copyright (C) 2005 Sumisho Computer Systems Corp.
 */
package jp.co.scs.mbench.component;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import jp.co.scs.mbench.BenchmarkTerminateException;
import jp.co.scs.mbench.Finalizer;

/**
 *  	Finalizer which calculate average,
 *      maximum and minimum of response time from all data files
 *      and overwrite them.
 * 
 *  	@author Masato Koga
 */
public class ResponseStatisticFinalizer implements Finalizer {
    private String finalizerName = null;

    public String getFinalizerName() {
        return this.finalizerName;
    }
    
    public void setFinalizerName(String finalizerName) {
        this.finalizerName = finalizerName;
    }

    
    /**
     *  Reads response time from all data files,
     *  and calculate average, maximum and minimum.
     */
    public void execute() throws BenchmarkTerminateException {
        // Get the all files on current directry
        File file = new File(".");
        File[] files = file.listFiles();
        
        for (int i = 0; i < files.length; i++) {
            String fileName = files[i].getName();
            // Check the file which is a data file.
            if (fileName.startsWith("data_") && fileName.endsWith(".csv")) {
                calculate(files[i]);
            }
        }
    }
    
    private void calculate(File file) throws BenchmarkTerminateException {
        InputStreamReader ir = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;
        int maxResponseTime = 0;
        int minResponseTime = 0;
        long sumResponseTime = 0;
        
        try {
            ir = new InputStreamReader(new FileInputStream(file));
            reader = new BufferedReader(ir);
            
            // Read the header.(ignore)
            reader.readLine();
            
            // initialize read
            int lineCount = 0;
            String lineStr = reader.readLine();
            
            // check the statement of data
            while (lineStr != null && !lineStr.startsWith("M")) {
                lineCount++;
                // read the value of response time.
                int responseTime = readValue(lineStr, 4);
                if (responseTime > maxResponseTime || lineCount == 1) {
                    maxResponseTime = responseTime;
                }
                if (responseTime < minResponseTime || lineCount == 1) {
                    minResponseTime = responseTime;
                }
                // calculate total of responstime
                sumResponseTime = sumResponseTime + responseTime;
                // read the value of end time.
                readValue(lineStr, 3);
                
                lineStr = reader.readLine();
            }
            
            if (lineStr == null) {
                writer = new BufferedWriter(new FileWriter(file, true));
                writer.write("Min Response Time :,,,," + minResponseTime + "\n");
                writer.write("Max Response Time :,,,," + maxResponseTime + "\n");
                writer.write("Avg Response Time :,,,," + (float) sumResponseTime / lineCount + "\n");
                System.out.println("Data file: \"" + file.getName()
                        + "\" is calculated");
            } else {
                System.out.println("Data file: \"" + file.getName()
                        + "\" has been already calculated");
            }
        } catch (Exception ex) {
            System.out.println("Data file: \"" + file.getName()
                    + "\" has an irregular  format");
        } finally {
            try {
                if (ir != null) {
                    ir.close();
                }
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException ex) {
                // ignore
            }
            
        }
    }
    
    /**
     *  Read the assigned item.
     * 
     *  @param lineStr A statement from data file
     *  @param number number of item
     *  @return value of item
     */
    private int readValue(String lineStr, int number) {
        int fromIndex = 0;
        for (int i = 0; i < number; i++) {
            fromIndex = lineStr.indexOf(',', fromIndex)  + 1;
        }
        int endIndex = lineStr.indexOf(',', fromIndex);
        return Integer.parseInt(lineStr.substring(fromIndex, endIndex));
    }
}
