/*                          
 * 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 java.util.LinkedList;

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

/**
 *  	Finalizer which calculate throughput in one second interval.
 * 
 *  	@author Masato Koga
 */
public class ThroughputStatisticFinalizer 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;
        
        try {
            ir = new InputStreamReader(new FileInputStream(file));
            reader = new BufferedReader(ir);
            
            // Read the header.(ignore)
            reader.readLine();
            
            // initialize read
            String lineStr = reader.readLine();
            
        	LinkedList throughPutList = new LinkedList();
            int sec = 1;
            
            // check the statement of data
            while (lineStr != null && !lineStr.startsWith("M")) {
                int tx = 0;
                
                // read the value of end time.
                int endTime = readValue(lineStr, 3);
                
                while (lineStr != null && !lineStr.startsWith("M") && endTime < sec * 1000) {
                	tx++;
                    lineStr = reader.readLine();
                    if (lineStr != null  && !lineStr.startsWith("M")) {
                        endTime = readValue(lineStr, 3);
                    }
                }
                throughPutList.add(new Integer(tx));
            	sec++;
            }
            
            // write throughput count
            String fileName = "throughput_" + file.getName().substring(5);
            writer = new BufferedWriter(new FileWriter(fileName));
            for (int i = 0; i < throughPutList.size(); i++) {
                writer.write( (i+1) + "," + ((Integer) throughPutList.get(i)).toString() + "\n");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            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));
    }
}
