package no.nr.edw.imporant;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import no.nr.edw.imporant.Analyser.RelationSet;

public class ConsoleWriter {
    private final Map<String, RelationSet> analysisResult;

    public ConsoleWriter(final Map<String, RelationSet> map) {
        if (map == null)
            throw new IllegalArgumentException();
        this.analysisResult = map;
    }

    public void write(final PrintWriter printWriter) {
        for (final String fromName : getTypeNamesSorted()) {
            final List<Entry<String, Integer>> relationsSorted = getRelationsSorted(fromName);
            final int numOccurrences = analysisResult.get(fromName).getNumOccurrences();

            if (
                relationsSorted.isEmpty() 
                || toPercent(relationsSorted.get(0).getValue(), numOccurrences) < 45.0
                || numOccurrences < 35
            )
                continue;
            
            printWriter.printf(" Type %s\n", fromName);
            printWriter.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            for (final Map.Entry<String, Integer> relation : relationsSorted) {
                if (toPercent(relation.getValue(), numOccurrences) < 20.0)
                    break;
                printWriter.printf(
                    " %3d [%3.2f%%] occurrences with %s\n", 
                    relation.getValue(), 
                    toPercent(relation.getValue(), numOccurrences),
                    relation.getKey()
                );
            }
            printWriter.println();
        }
    }

    private double toPercent(final int n, final int d) {
        return 100.0 * n / (double) d;
    }

    private List<Map.Entry<String, Integer>> getRelationsSorted(final String fromName) {
        final List<Map.Entry<String, Integer>> res = new ArrayList<Map.Entry<String, Integer>>(
            analysisResult.get(fromName).getRelations().entrySet()
        );
        Collections.sort(res, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(final Entry<String, Integer> a, final Entry<String, Integer> b) {
                final int firstPivot = b.getValue() - a.getValue();
                return firstPivot != 0 ? firstPivot : a.getKey().compareTo(b.getKey());
            }
        });
        return res; 
    }

    private List<String> getTypeNamesSorted() {
        final List<String> res = new ArrayList<String>(analysisResult.keySet());
        Collections.sort(res);
        return res;
    }

}
