package aQute.bnd.make.calltree;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import aQute.lib.osgi.*;

/**
 * Create an XML call tree of a set of classes. The structure of the XML is:
 * 
 * <pre>
 *    calltree ::= &lt;using&gt; &lt;usedby&gt;
 *    using    ::= &lt;method&gt; *
 *    usedby   ::= &lt;method&gt; *
 *    method   ::= &lt;ref&gt; 
 * </pre>
 * 
 * The <code>using</code> element contains methods in the set of classes and
 * their references. The <code>usedby</code> element contains the used methods
 * and their references to the set of classes. The <code>ref</code> element
 * contains the class, the method name, the descriptor, and a pretty print
 * version of the method.
 * 
 * The XML does not contain an XML processor instruction to make it easier to
 * include in other XML. The encoding is always UTF-8.
 * 
 * This class can be used as a resource, just add it to a JAR and the data is
 * generated when the resource is written (saving time when the JAR is up to
 * date and does not have to be generated). However, the actual write method is
 * a static method and can be called as well:
 * {@link #writeCalltree(PrintWriter, Collection)}.
 */
public class CalltreeResource extends WriteResource {
    Collection<Clazz> classes;

    /**
     * Create a resource for inclusion that will print a call tree.
     * 
     * @param values the classes for which the call tree is generated.
     */
    public CalltreeResource(Collection<Clazz> values) {
        this.classes = values;
        System.out.println(values);
    }

    /**
     * We set the last modified to 0 so this resource does not force
     * a new JAR if all other resources are up to date.
     */
    public long lastModified() {
        return 0;
    }

    /**
     * The write method is called to write the resource. We just call the static
     * method.
     */
    public void write(OutputStream out) throws Exception {
        OutputStreamWriter osw = new OutputStreamWriter(out, Constants.DEFAULT_CHARSET);
        PrintWriter pw = new PrintWriter(osw);
        try {
            writeCalltree(pw, classes);
        } finally {
            pw.flush();
        }
    }

    /**
     * Print the call tree in XML.
     * 
     * @param out The output writer
     * @param classes The set of classes
     * @throws IOException Any errors
     */
    public static void writeCalltree(PrintWriter out, Collection<Clazz> classes)
            throws Exception {

        final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> using = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>();
        final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> usedby = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>();

        ClassDataCollector cd = new ClassDataCollector() {
            Clazz.MethodDef source;

            // Before a method is parsed
            public void method(Clazz.MethodDef source) {
                this.source = source;
                xref(using, source, null);
                xref(usedby, source, null);
            }

            // For any reference in the previous method.
            public void reference(Clazz.MethodDef reference) {
                xref(using, source, reference);
                xref(usedby, reference, source);
            }
        };
        for (Clazz clazz : classes) {
            clazz.parseClassFileWithCollector(cd);
        }

        out.println("<calltree>");
        xref(out, "using", using);
        xref(out, "usedby", usedby);
        out.println("</calltree>");
    }

    /*
     * Add a new reference
     */
    private static void xref(
            Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references,
            Clazz.MethodDef source, Clazz.MethodDef reference) {
        Set<Clazz.MethodDef> set = references.get(source);
        if (set == null)
            references.put(source, set=new TreeSet<Clazz.MethodDef>());
        if ( reference != null)
            set.add(reference);
    }

    /*
     * Print out either using or usedby sets
     */
    private static void xref(PrintWriter out, String group,
            Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references) {
        out.println("  <" + group + ">");
        for (Map.Entry<Clazz.MethodDef, Set<Clazz.MethodDef>> entry : references
                .entrySet()) {
            Clazz.MethodDef source = entry.getKey();
            Set<Clazz.MethodDef> refs = entry.getValue();
            method(out, "method", source, ">");
            for (Clazz.MethodDef ref : refs) {
                method(out, "ref", ref, "/>");
            }
            out.println("      </method>");
        }
        out.println("  </" + group + ">");
    }

    /*
     * Print out a method.
     */
    private static void method(PrintWriter out, String element,
            Clazz.MethodDef source, String closeElement) {
        out.println("      <" + element + " class='" + source.clazz + "'"
                + getAccess(source.access) + 
                ( source.isConstructor() ? "" :  " name='" + source.name + "'") + " descriptor='" + source.descriptor + "' pretty='"
                + source.getPretty() + "'" + closeElement);
    }

    private static String getAccess(int access) {
        StringBuilder sb = new StringBuilder();
        if ( Modifier.isPublic(access) )
            sb.append(" public='true'");
        if ( Modifier.isStatic(access) )
            sb.append(" static='true'");
        if ( Modifier.isProtected(access) )
            sb.append(" protected='true'");
        if ( Modifier.isInterface(access) )
            sb.append(" interface='true'");
        
        return sb.toString();
    }

}
