/**
*******************************************************************************
* Copyright (C) 2004-2006, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

/**
 * Compare two API files (generated by GatherAPIData) and generate a report
 * on the differences.
 *
 * Sample invocation:
 * java -old: icu4j28.api.zip -new: icu4j30.api -html -out: icu4j_compare_28_30.html
 *
 * TODO:
 * - make 'changed apis' smarter - detect method parameter or return type change
 *   for this, the sequential search through methods ordered by signature won't do.
 *     We need to gather all added and removed overloads for a method, and then
 *     compare all added against all removed in order to identify this kind of
 *     change.
 */

package com.ibm.icu.dev.tool.docs;

import java.io.*;
import java.util.*;
import java.text.*;

public class ReportAPI {
    APIData oldData;
    APIData newData;
    boolean html;
    String outputFile;

    TreeSet added;
    TreeSet removed;
    TreeSet promoted;
    TreeSet obsoleted;
    ArrayList changed;

    static final class DeltaInfo extends APIInfo {
        APIInfo added;
        APIInfo removed;

        DeltaInfo(APIInfo added, APIInfo removed) {
            this.added = added;
            this.removed = removed;
        }

        public int getVal(int typ) {
            return added.getVal(typ);
        }

        public String get(int typ, boolean brief) {
            return added.get(typ, brief);
        }

        public void print(PrintWriter pw, boolean detail, boolean html) {
            pw.print("    ");
            removed.print(pw, detail, html);
            if (html) {
                pw.println("</br>");
            } else {
                pw.println();
                pw.print("--> ");
            }
            added.print(pw, detail, html);
        }
    }

    public static void main(String[] args) {
        String oldFile = null;
        String newFile = null;
        String outFile = null;
        boolean html = false;
        boolean internal = false;
        for (int i = 0; i < args.length; ++i) {
            String arg = args[i];
            if (arg.equals("-old:")) {
                oldFile = args[++i];
            } else if (arg.equals("-new:")) {
                newFile = args[++i];
            } else if (arg.equals("-out:")) {
                outFile = args[++i];
            } else if (arg.equals("-html")) {
                html = true;
            } else if (arg.equals("-internal")) {
                internal = true;
            }
        }

        new ReportAPI(oldFile, newFile, internal).writeReport(outFile, html, internal);
    }

    /*
      while the both are methods and the class and method names are the same, collect
      overloads.  when you hit a new method or class, compare the overloads
      looking for the same # of params and simple param changes.  ideally
      there are just a few.

      String oldA = null;
      String oldR = null;
      if (!a.isMethod()) {
      remove and continue
      }
      String am = a.getClassName() + "." + a.getName();
      String rm = r.getClassName() + "." + r.getName();
      int comp = am.compare(rm);
      if (comp == 0 && a.isMethod() && r.isMethod())

    */

    ReportAPI(String oldFile, String newFile, boolean internal) {
        this(APIData.read(oldFile, internal), APIData.read(newFile, internal));
    }

    ReportAPI(APIData oldData, APIData newData) {
        this.oldData = oldData;
        this.newData = newData;

        removed = (TreeSet)oldData.set.clone();
        removed.removeAll(newData.set);

        added = (TreeSet)newData.set.clone();
        added.removeAll(oldData.set);

        changed = new ArrayList();
        Iterator ai = added.iterator();
        Iterator ri = removed.iterator();
        Comparator c = APIInfo.changedComparator();

        ArrayList ams = new ArrayList();
        ArrayList rms = new ArrayList();
        PrintWriter outpw = new PrintWriter(System.out);

        APIInfo a = null, r = null;
        while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
            if (a == null) a = (APIInfo)ai.next();
            if (r == null) r = (APIInfo)ri.next();

            String am = a.getClassName() + "." + a.getName();
            String rm = r.getClassName() + "." + r.getName();
            int comp = am.compareTo(rm);
            if (comp == 0 && a.isMethod() && r.isMethod()) { // collect overloads
                ams.add(a); a = null;
                rms.add(r); r = null;
                continue;
            }

            if (!ams.isEmpty()) {
                // simplest case first
                if (ams.size() == 1 && rms.size() == 1) {
                    changed.add(new DeltaInfo((APIInfo)ams.get(0), (APIInfo)rms.get(0)));
                } else {
                    // dang, what to do now?
                    // TODO: modify deltainfo to deal with lists of added and removed
                }
                ams.clear();
                rms.clear();
            }

            int result = c.compare(a, r);
            if (result < 0) {
                a = null;
            } else if (result > 0) {
                r = null;
            } else {
                changed.add(new DeltaInfo(a, r));
                a = null;
                r = null;
            }
        }

        // now clean up added and removed by cleaning out the changed members
        Iterator ci = changed.iterator();
        while (ci.hasNext()) {
            DeltaInfo di = (DeltaInfo)ci.next();
            added.remove(di.added);
            removed.remove(di.removed);
        }

        Set tempAdded = new HashSet();
        tempAdded.addAll(newData.set);
        tempAdded.removeAll(removed);
        TreeSet changedAdded = new TreeSet(APIInfo.defaultComparator());
        changedAdded.addAll(tempAdded);

        Set tempRemoved = new HashSet();
        tempRemoved.addAll(oldData.set);
        tempRemoved.removeAll(added);
        TreeSet changedRemoved = new TreeSet(APIInfo.defaultComparator());
        changedRemoved.addAll(tempRemoved);

        promoted = new TreeSet(APIInfo.defaultComparator());
        obsoleted = new TreeSet(APIInfo.defaultComparator());
        ai = changedAdded.iterator();
        ri = changedRemoved.iterator();
        a = r = null;
        while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
            if (a == null) a = (APIInfo)ai.next();
            if (r == null) r = (APIInfo)ri.next();
            int result = c.compare(a, r);
            if (result < 0) {
                a = null;
            } else if (result > 0) {
                r = null;
            } else {
                int change = statusChange(a, r);
                if (change > 0) {
                    promoted.add(a);
                } else if (change < 0) {
                    obsoleted.add(a);
                }
                a = null;
                r = null;
            }
        }

        added = stripAndResort(added);
        removed = stripAndResort(removed);
        promoted = stripAndResort(promoted);
        obsoleted = stripAndResort(obsoleted);
    }

    private int statusChange(APIInfo lhs, APIInfo rhs) { // new. old
        for (int i = 0; i < APIInfo.NUM_TYPES; ++i) {
            if (lhs.get(i, true).equals(rhs.get(i, true)) == (i == APIInfo.STA)) {
                return 0;
            }
        }
        int lstatus = lhs.getVal(APIInfo.STA);
        if (lstatus == APIInfo.STA_OBSOLETE || lstatus == APIInfo.STA_DEPRECATED || lstatus == APIInfo.STA_INTERNAL) {
            return -1;
        }
        return 1;
    }

    private boolean writeReport(String outFile, boolean html, boolean internal) {
        OutputStream os = System.out;
        if (outFile != null) {
            try {
                os = new FileOutputStream(outFile);
            }
            catch (FileNotFoundException e) {
                RuntimeException re = new RuntimeException(e.getMessage());
                re.initCause(e);
                throw re;
            }
        }

        PrintWriter pw = null;
        try {
            pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os, "UTF-8")));
        }
        catch (UnsupportedEncodingException e) {
            throw new IllegalStateException(); // UTF-8 should always be supported
        }

        DateFormat fmt = new SimpleDateFormat("yyyy");
        String year = fmt.format(new Date());
        String title = "ICU4J API Comparison: " + oldData.name + " with " + newData.name;
        String info = "Contents generated by ReportAPI tool on " + new Date().toString();
        String copyright = "Copyright (C) " + year + ", International Business Machines Corporation, All Rights Reserved.";

        if (html) {
            pw.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
            pw.println("<html>");
            pw.println("<head>");
            pw.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
            pw.println("<title>" + title + "</title>");
            pw.println("<!-- Copyright " + year + ", IBM, All Rights Reserved. -->");
            pw.println("</head>");
            pw.println("<body>");

            pw.println("<h1>" + title + "</h1>");

            pw.println();
            pw.println("<hr/>");
            pw.println("<h2>Removed from " + oldData.name +"</h2>");
            if (removed.size() > 0) {
                printResults(removed, pw, true, false);
            } else {
                pw.println("<p>(no API removed)</p>");
            }

            pw.println();
            pw.println("<hr/>");
            if (internal) {
                pw.println("<h2>Withdrawn, Deprecated, or Obsoleted in " + newData.name + "</h2>");
            } else {
                pw.println("<h2>Deprecated or Obsoleted in " + newData.name + "</h2>");
            }
            if (obsoleted.size() > 0) {
                printResults(obsoleted, pw, true, false);
            } else {
                pw.println("<p>(no API obsoleted)</p>");
            }

            pw.println();
            pw.println("<hr/>");
            pw.println("<h2>Changed in " + newData.name + " (old, new)</h2>");
            if (changed.size() > 0) {
                printResults(changed, pw, true, true);
            } else {
                pw.println("<p>(no API changed)</p>");
            }

            pw.println();
            pw.println("<hr/>");
            pw.println("<h2>Promoted to stable in " + newData.name + "</h2>");
            if (promoted.size() > 0) {
                printResults(promoted, pw, true, false);
            } else {
                pw.println("<p>(no API promoted)</p>");
            }

            pw.println();
            pw.println("<hr/>");
            pw.println("<h2>Added in " + newData.name + "</h2>");
            if (added.size() > 0) {
                printResults(added, pw, true, false);
            } else {
                pw.println("<p>(no API added)</p>");
            }

            pw.println("<hr/>");
            pw.println("<p><i><font size=\"-1\">" + info + "<br/>" + copyright + "</font></i></p>");
            pw.println("</body>");
            pw.println("</html>");
        } else {
            pw.println(title);
            pw.println();
            pw.println();

            pw.println("=== Removed from " + oldData.name + " ===");
            if (removed.size() > 0) {
                printResults(removed, pw, false, false);
            } else {
                pw.println("(no API removed)");
            }

            pw.println();
            pw.println();
            if (internal) {
                pw.println("=== Withdrawn, Deprecated, or Obsoleted in " + newData.name + " ===");
            } else {
                pw.println("=== Deprecated or Obsoleted in " + newData.name + " ===");
            }
            if (obsoleted.size() > 0) {
                printResults(obsoleted, pw, false, false);
            } else {
                pw.println("(no API obsoleted)");
            }

            pw.println();
            pw.println();
            pw.println("=== Changed in " + newData.name + " (old, new) ===");
            if (changed.size() > 0) {
                printResults(changed, pw, false, true);
            } else {
                pw.println("(no API changed)");
            }

            pw.println();
            pw.println();
            pw.println("=== Promoted to stable in " + newData.name + " ===");
            if (promoted.size() > 0) {
                printResults(promoted, pw, false, false);
            } else {
                pw.println("(no API promoted)");
            }

            pw.println();
            pw.println();
            pw.println("=== Added in " + newData.name + " ===");
            if (added.size() > 0) {
                printResults(added, pw, false, false);
            } else {
                pw.println("(no API added)");
            }

            pw.println();
            pw.println("================");
            pw.println(info);
            pw.println(copyright);
        }
        pw.close();

        return false;
    }

    private static void printResults(Collection c, PrintWriter pw, boolean html, boolean isChangedAPIs) {
        Iterator iter = c.iterator();
        String pack = null;
        String clas = null;
        while (iter.hasNext()) {
            APIInfo info = (APIInfo)iter.next();

            String packageName = info.getPackageName();
            if (!packageName.equals(pack)) {
                if (html) {
                    if (clas != null) {
                        pw.println("</ul>");
                    }
                    if (pack != null) {
                        pw.println("</ul>");
                    }
                    pw.println();
                    pw.println("<h3>Package " + packageName + "</h3>");
                    pw.print("<ul>");
                } else {
                    if (pack != null) {
                        pw.println();
                    }
                    pw.println();
                    pw.println("Package " + packageName + ":");
                }
                pw.println();

                pack = packageName;
                clas = null;
            }

            if (!info.isClass()) {
                String className = info.getClassName();
                if (!className.equals(clas)) {
                    if (html) {
                        if (clas != null) {
                            pw.println("</ul>");
                        }
                        pw.println(className);
                        pw.println("<ul>");
                    } else {
                        pw.println(className);
                    }
                    clas = className;
                }
            }

            if (html) {
                pw.print("<li>");
                info.print(pw, isChangedAPIs, html);
                pw.println("</li>");
            } else {
                info.println(pw, isChangedAPIs, html);
            }
        }

        if (html) {
            if (clas != null) {
                pw.println("</ul>");
            }
            if (pack != null) {
                pw.println("</ul>");
            }
        }
        pw.println();
    }

    private static TreeSet stripAndResort(TreeSet t) {
        stripClassInfo(t);
        TreeSet r = new TreeSet(APIInfo.classFirstComparator());
        r.addAll(t);
        return r;
    }

    private static void stripClassInfo(Collection c) {
        // c is sorted with class info first
        Iterator iter = c.iterator();
        String cname = null;
        while (iter.hasNext()) {
            APIInfo info = (APIInfo)iter.next();
            String className = info.getClassName();
            if (cname != null) {
                if (cname.equals(className)) {
                    iter.remove();
                    continue;
                }
                cname = null;
            }
            if (info.isClass()) {
                cname = info.getName();
            }
        }
    }
}
