package accrue.analysis;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;

import polyglot.types.CodeInstance;
import polyglot.types.ConstructorInstance;
import polyglot.types.MethodInstance;

public abstract class MissingCodeReporter {
    private static HashMap<String, SortedSet<String>> analysisMissingCode =
            new HashMap<String, SortedSet<String>>();
    private static SortedSet<String> missingCode = new TreeSet<String>();

    public static void reportMissingCode(String analysisName, CodeInstance ci) {
        if (!analysisMissingCode.containsKey(analysisName)) {
            analysisMissingCode.put(analysisName, new TreeSet<String>());
        }
        SortedSet<String> missingCodeForAnalysis =
                analysisMissingCode.get(analysisName);
        String reportString;
        if (ci instanceof MethodInstance) {
            MethodInstance m = (MethodInstance) ci;
            reportString =
                    m.container() + ": " + m.flags() + " " + m.returnType()
                            + " " + m.signature();
        }
        else if (ci instanceof ConstructorInstance) {
            ConstructorInstance c = (ConstructorInstance) ci;
            reportString =
                    c.container() + ": " + c.flags() + " " + c.signature();
        }
        else {
            reportString = ci.toString();
        }
        analysisMissingCode.get(analysisName).add(reportString);
        missingCode.add(reportString);
    }

    public static void reportToFile(String filename) throws IOException {
        PrintStream file = new PrintStream(new File(filename));
        print(file);
        file.close();
    }

    public static void reportToStdErr() {
        print(System.err);
    }

    public static void reportToStdOut() {
        print(System.out);
    }

    public static void print(PrintStream out) {
        for (String key : analysisMissingCode.keySet()) {
            out.println("Missing code for analysis " + key);
            for (String code : analysisMissingCode.get(key)) {
                out.println("\t" + code);
            }
        }
        out.println("Missing code from any analysis");
        for (String code : missingCode) {
            out.println("\t" + code);
        }
    }
}
