/**
*******************************************************************************
* Copyright (C) 2004-2010, 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.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

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

    TreeSet<APIInfo> added;
    TreeSet<APIInfo> removed;
    TreeSet<APIInfo> promoted;
    TreeSet<APIInfo> obsoleted;
    ArrayList<DeltaInfo> 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<APIInfo>)oldData.set.clone();
        removed.removeAll(newData.set);

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

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

        ArrayList<APIInfo> ams = new ArrayList<APIInfo>();
        ArrayList<APIInfo> rms = new ArrayList<APIInfo>();
        //PrintWriter outpw = new PrintWriter(System.out);

        APIInfo a = null, r = null;
        while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
            if (a == null) a = ai.next();
            if (r == null) r = 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(ams.get(0), 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<DeltaInfo> ci = changed.iterator();
        while (ci.hasNext()) {
            DeltaInfo di = ci.next();
            added.remove(di.added);
            removed.remove(di.removed);
        }

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

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

        promoted = new TreeSet<APIInfo>(APIInfo.defaultComparator());
        obsoleted = new TreeSet<APIInfo>(APIInfo.defaultComparator());
        ai = changedAdded.iterator();
        ri = changedRemoved.iterator();
        a = r = null;
        while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
            if (a == null) a = ai.next();
            if (r == null) r = 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<? extends APIInfo> c, PrintWriter pw, boolean html,
                                     boolean isChangedAPIs) {
        Iterator<? extends APIInfo> iter = c.iterator();
        String pack = null;
        String clas = null;
        while (iter.hasNext()) {
            APIInfo info = 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<APIInfo> stripAndResort(TreeSet<APIInfo> t) {
        stripClassInfo(t);
        TreeSet<APIInfo> r = new TreeSet<APIInfo>(APIInfo.classFirstComparator());
        r.addAll(t);
        return r;
    }

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