package org.eclipse.indigo.tests;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class FeatureNameLengths {

    private String inputFileName = "/home/davidw/temp/indigoFeatures.txt";
    private Map    distribution  = null;

    public static <T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
        List<T> list = new ArrayList<T>(c);
        java.util.Collections.sort(list);
        return list;
    }

    public static void main(String[] args) {

        try {
            new FeatureNameLengths().analyze(args);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void analyze(String[] args) throws IOException {
        distribution = new HashMap<Integer, Integer>();
        File inputFile = new File(inputFileName);
        Reader inputReader = new FileReader(inputFile);
        BufferedReader input = new BufferedReader(inputReader);
        String line = null;
        // should this be 'if' or 'while'
        if (inputReader.ready()) {
            line = input.readLine();
            while (line != null) {
                // ignore if length is zero (just empty line in input file, not feature name)
                if (line.length() > 0) {
                    //System.out.println(line.length());
                    tabulate(line.length());
                }
                line = input.readLine();
            }
        }
        printReport();
    }

    private void printReport() {
        Integer total = new Integer(0);
        System.out.println("Distribution of line lengths in " + inputFileName);
        Set keys = distribution.keySet();
        List<Integer> list = asSortedList(keys);
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Integer category = (Integer) iterator.next();
            Integer count = (Integer) distribution.get(category);
            System.out.println("\t" + category + "\t" + count);
            total = total + count;
        }
        System.out.println("\nTotal lines (features): " + total);

    }

    private void tabulate(int length) {
        Integer category = new Integer(length);
        Integer count = (Integer) distribution.get(category);
        if (count == null) {
            // our first occurance
            count = new Integer(1);
        }
        else {
            count = count + 1;
        }
        distribution.put(category, count);
    }
}
