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

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

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

/**
 * Compare ICU4J and JDK APIS.
 *
 * TODO: compare protected APIs.  Reflection on Class allows you
 * to either get all inherited methods with public access, or get methods
 * on the particular class with any access, but no way to get all
 * inherited methods with any access.  Go figure.
 */
public class ICUJDKCompare {
    static final boolean DEBUG = false;

    // set up defaults
    private static final String kSrcPrefix = "java.";
    private static final String kTrgPrefix = "com.ibm.icu.";
    private static final String[] kPairInfo = {
        "lang.Character/UCharacter",
        "lang.Character$UnicodeBlock/UCharacter$UnicodeBlock",
        "text.BreakIterator",
        "text.Collator",
        "text.DateFormat",
        "text.DateFormatSymbols",
        "text.DecimalFormat",
        "text.DecimalFormatSymbols",
        "text.Format/UFormat",
        "text.MessageFormat",
        "text.NumberFormat",
        "text.SimpleDateFormat",
        "util.Calendar",
        "util.Currency",
        "util.GregorianCalendar",
        "util.SimpleTimeZone",
        "util.TimeZone",
        "util.Locale/ULocale",
        "util.ResourceBundle/UResourceBundle",
    };

    private static final String[] kIgnore = new String[] {
        "lang.Character <init> charValue compareTo MAX_VALUE MIN_VALUE TYPE",
        "lang.Character$UnicodeBlock SURROGATES_AREA",
        "util.Calendar FIELD_COUNT",
        "util.GregorianCalendar FIELD_COUNT",
        "util.SimpleTimeZone STANDARD_TIME UTC_TIME WALL_TIME",
    };

    private PrintWriter pw;
    private String srcPrefix;
    private String trgPrefix;
    private Class[] classPairs;
    private String[] namePairs;
    private String[] ignore;
    private boolean swap;
    private boolean signature;

    // call System.exit with non-zero if there were some missing APIs
    public static void main(String[] args) {
        System.exit(doMain(args));
    }

    // return non-zero if there were some missing APIs
    public static int doMain(String[] args) {
        ICUJDKCompare p = new ICUJDKCompare();
        p.setOutputWriter(new PrintWriter(System.out));
        p.setup(args);
        return p.process();
    }

    // setters
    public ICUJDKCompare setOutputWriter(PrintWriter pw) {
        this.pw = pw;
        return this;
    }

    public ICUJDKCompare setSrcPrefix(String srcPrefix) {
        this.srcPrefix = srcPrefix;
        return this;
    }

    public ICUJDKCompare setTrgPrefix(String trgPrefix) {
        this.trgPrefix = trgPrefix;
        return this;
    }

    public ICUJDKCompare setClassPairs(Class[] classPairs) {
        this.classPairs = classPairs;
        return this;
    }

    public ICUJDKCompare setNamePairs(String[] namePairs) {
        this.namePairs = namePairs;
        return this;
    }

    public ICUJDKCompare setIgnore(String[] ignore) {
        this.ignore = ignore;
        return this;
    }

    public ICUJDKCompare setSwap(boolean swap) {
        this.swap = swap;
        return this;
    }

    public ICUJDKCompare setup(String[] args) {
        String namelist = null;
        String ignorelist = null;
        for (int i = 0; i < args.length; ++i) {
            String arg = args[i];
            if (arg.equals("-swap")) {
                swap = true;
            } else if (arg.equals("-srcPrefix:")) {
                srcPrefix = args[++i];
                if (!srcPrefix.endsWith(".")) {
                    srcPrefix += '.';
                }
            } else if (arg.equals("-trgPrefix:")) {
                trgPrefix = args[++i];
                if (!trgPrefix.endsWith(".")) {
                    trgPrefix += '.';
                }
            } else if (arg.equals("-names:")) {
                namelist = args[++i];
            } else if (arg.equals("-ignore:")) {
                ignorelist = args[++i];
            } else {
                System.err.println("unrecognized argument: " + arg);
                throw new IllegalStateException();
            }
        }

        if (ignorelist != null) {
            if (ignorelist.charAt(0) == '@') { // a file containing ignoreinfo
                try {
                    ArrayList nl = new ArrayList();
                    File f = new File(namelist.substring(1));
                    FileInputStream fis = new FileInputStream(f);
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader br = new BufferedReader(isr);
                    String line = null;
                    while (null != (line = br.readLine())) {
                        nl.add(line);
                    }
                    ignore = (String[])nl.toArray(new String[nl.size()]);
                }
                catch (Exception e) {
                    System.err.println(e);
                    throw new IllegalStateException();
                }
            } else { // a list of ignoreinfo separated by semicolons
                ignore = ignorelist.split("\\s*;\\s*");
            }
        }

        if (namelist != null) {
            String[] names = null;
            if (namelist.charAt(0) == '@') { // a file
                try {
                    ArrayList nl = new ArrayList();
                    File f = new File(namelist.substring(1));
                    FileInputStream fis = new FileInputStream(f);
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader br = new BufferedReader(isr);
                    String line = null;
                    while (null != (line = br.readLine())) {
                        nl.add(line);
                    }
                    names = (String[])nl.toArray(new String[nl.size()]);
                }
                catch (Exception e) {
                    System.err.println(e);
                    throw new IllegalStateException();
                }
            } else { // a list of names separated by semicolons
                names = namelist.split("\\s*;\\s*");
            }

            processPairInfo(names);
        }

        pw.flush();

        return this;
    }

    private void processPairInfo(String[] names) {
        ArrayList cl = new ArrayList();
        ArrayList nl = new ArrayList();
        for (int i = 0; i < names.length; ++i) {
            String name = names[i];
            String srcName = srcPrefix;
            String trgName = trgPrefix;

            int n = name.indexOf('/');
            if (n == -1) {
                srcName += name;
                trgName += name;
            } else {
                String srcSuffix = name.substring(0, n).trim();
                String trgSuffix = name.substring(n+1).trim();
                int jx = srcSuffix.length()+1;
                int ix = trgSuffix.length()+1;
                while (ix != -1) {
                    jx = srcSuffix.lastIndexOf('.', jx-1);
                    ix = trgSuffix.lastIndexOf('.', ix-1);
                }
                srcName += srcSuffix;
                trgName += srcSuffix.substring(0, jx+1) + trgSuffix;
            }

            try {
                Class jc = Class.forName(srcName);
                Class ic = Class.forName(trgName);
                cl.add(ic);
                cl.add(jc);
                nl.add(ic.getName());
                nl.add(jc.getName());
            }
            catch (Exception e) {
                if (DEBUG) System.err.println("can't load class: " + e.getMessage());
            }
        }
        classPairs = (Class[])cl.toArray(new Class[cl.size()]);
        namePairs = (String[])nl.toArray(new String[nl.size()]);
    }

    private void println(String s) {
        if (pw != null) pw.println(s);
    }

    private void flush() {
        if (pw != null) pw.flush();
    }

    public int process() {
        // set defaults
        if (srcPrefix == null) {
            srcPrefix = kSrcPrefix;
        }

        if (trgPrefix == null) {
            trgPrefix = kTrgPrefix;
        }
        
        if (classPairs == null) {
            processPairInfo(kPairInfo);
        }

        if (ignore == null) {
            ignore = kIgnore;
        }

        println("ICU and Java API Comparison");
        String ICU_VERSION = "unknown";
        try {
            Class cls = Class.forName("com.ibm.icu.util.VersionInfo");
            Field fld = cls.getField("ICU_VERSION");
            ICU_VERSION = fld.get(null).toString();
        }
        catch (Exception e) {
            if (DEBUG) System.err.println("can't get VersionInfo: " + e.getMessage());
        }
        println("ICU Version " + ICU_VERSION);
        println("JDK Version " + System.getProperty("java.version"));

        int errorCount = 0;
        for (int i = 0; i < classPairs.length; i += 2) {
            try {
                if (swap) {
                    errorCount += compare(classPairs[i+1], classPairs[i]);
                } else {
                    errorCount += compare(classPairs[i], classPairs[i+1]);
                }
            }
            catch (Exception e) {
                System.err.println("exception: " + e);
                System.err.println("between " + namePairs[i] + " and " + namePairs[i+1]);
                e.printStackTrace();
                errorCount += 1;
            }
        }
        return errorCount;
    }

    static class MorC {
        private Method mref;
        private Constructor cref;

        MorC(Method m) {
            mref = m;
        }

        MorC(Constructor c) {
            cref = c;
        }

        int getModifiers() {
            return mref == null ? cref.getModifiers() : mref.getModifiers();
        }

        Class getReturnType() {
            return mref == null ? void.class : mref.getReturnType();
        }

        Class[] getParameterTypes() {
            return mref == null ? cref.getParameterTypes() : mref.getParameterTypes();
        }

        String getName() {
            return mref == null ? "<init>" : mref.getName();
        }

        String getSignature() {
            return mref == null ? cref.toString() : mref.toString();
        }
    }

    private int compare(Class class1, Class class2) throws Exception {
        String n1 = class1.getName();
        String n2 = class2.getName();

        println("\ncompare " + n1 + " <> " + n2);

        MorC[] conss1 = getMorCArray(class1.getConstructors());
        MorC[] conss2 = getMorCArray(class2.getConstructors());

        Map cmap1 = getMethodMap(conss1);
        Map cmap2 = getMethodMap(conss2);

        MorC[] meths1 = getMorCArray(class1.getMethods());
        MorC[] meths2 = getMorCArray(class2.getMethods());

        Map map1 = getMethodMap(meths1);
        Map map2 = getMethodMap(meths2);

        Field[] fields1 = class1.getFields();
        Field[] fields2 = class2.getFields();

        Set set1 = getFieldSet(fields1);
        Set set2 = getFieldSet(fields2);

        Map diffConss = diffMethodMaps(cmap2, cmap1);
        Map diffMeths = diffMethodMaps(map2, map1);
        Set diffFields = diffFieldSets(set2, set1);

        diffConss = removeIgnored(n2, diffConss);
        diffMeths = removeIgnored(n2, diffMeths);
        diffFields = removeIgnored(n2, diffFields);

        int result = diffConss.size() + diffMeths.size() + diffFields.size();
        if (result > 0 && pw != null) {
            pw.println("Public API in " + n2 + " but not in " + n1);
            if (diffConss.size() > 0) {
                pw.println("CONSTRUCTORS");
                dumpMethodMap(diffConss, pw);
            }
            if (diffMeths.size() > 0) {
                pw.println("METHODS");
                dumpMethodMap(diffMeths, pw);
            }
            if (diffFields.size() > 0) {
                pw.println("FIELDS");
                dumpFieldSet(diffFields, pw);
            }
        }

        flush();

        return result;
    }

    final class MethodRecord {
        MorC[] overrides;

        MethodRecord(MorC m) {
            overrides = new MorC[] { m };
        }

        MethodRecord(MorC[] ms) {
            overrides = ms;
        }

        MethodRecord copy() {
            return new MethodRecord((MorC[])overrides.clone());
        }

        int count() {
            for (int i = 0; i < overrides.length; ++i) {
                if (overrides[i] == null) {
                    return i;
                }
            }
            return overrides.length;
        }

        void add(MorC m) {
            MorC[] temp = new MorC[overrides.length + 1];
            for (int i = 0; i < overrides.length; ++i) {
                temp[i] = overrides[i];
            }
            temp[overrides.length] = m;
            overrides = temp;
        }

        void remove(int index) {
            int i = index;
            while (overrides[i] != null && i < overrides.length-1) {
                overrides[i] = overrides[i+1];
                ++i;
            }
            overrides[i] = null;
        }

        // if a call to a method can be handled by a call to t, remove the
        // method from our list, and return true
        boolean removeOverridden(MorC t) {
            boolean result = false;
            int i = 0;
            while (i < overrides.length) {
                MorC m = overrides[i];
                if (m == null) {
                    break;
                }
                if (handles(t, m)) {
                    remove(i);
                    result = true;
                } else {
                    ++i;
                }
            }
            return result;
        }

        // remove all methods handled by any method of mr
        boolean removeOverridden(MethodRecord mr) {
            boolean result = false;
            for (int i = 0; i < mr.overrides.length; ++i) {
                MorC t = mr.overrides[i];
                if (t == null) {
                    // this shouldn't happen, as the target record should not have been modified
                    throw new IllegalStateException();
                }
                if (removeOverridden(t)) {
                    result = true;
                }
            }
            return result;
        }

        void debugmsg(MorC t, MorC m, String msg) {
            StringBuffer buf = new StringBuffer();
            buf.append(t.getName());
            buf.append(" ");
            buf.append(msg);
            buf.append("\n   ");
            toString(t, buf);
            buf.append("\n   ");
            toString(m, buf);
            System.out.println(buf.toString());
        }

        boolean handles(MorC t, MorC m) {
            // relevant modifiers must match
            if ((t.getModifiers() & MOD_MASK) != (m.getModifiers() & MOD_MASK)) {
                if (DEBUG) debugmsg(t, m, "modifier mismatch");
                return false;
            }

            Class tr = pairClassEquivalent(t.getReturnType());
            Class mr = pairClassEquivalent(m.getReturnType());
            if (!assignableFrom(mr, tr)) { // t return type must be same or narrower than m
                if (DEBUG) debugmsg(t, m, "return value mismatch");
                return false;
            }
            Class[] tts = t.getParameterTypes();
            Class[] mts = m.getParameterTypes();
            if (tts.length != mts.length) {
                if (DEBUG) debugmsg(t, m, "param count mismatch");
                return false;
            }

            for (int i = 0; i < tts.length; ++i) {
                Class tc = pairClassEquivalent(tts[i]);
                Class mc = pairClassEquivalent(mts[i]);
                if (!assignableFrom(tc, mc)) { // m param must be same or narrower than t
                    if (DEBUG) debugmsg(t, m, "parameter " + i + " mismatch, " +
                                   tts[i].getName() + " not assignable from " + mts[i].getName());
                    return false;
                }
            }
            return true;
        }

        public void toString(MorC m, StringBuffer buf) {
            int mod = m.getModifiers();
            if (mod != 0) {
                buf.append(Modifier.toString(mod) + " ");
            }
            buf.append(nameOf(m.getReturnType()));
            buf.append(" ");
            buf.append(m.getName());
            buf.append("(");
            Class[] ptypes = m.getParameterTypes();
            for (int j = 0; j < ptypes.length; ++j) {
                if (j > 0) {
                    buf.append(", ");
                }
                buf.append(nameOf(ptypes[j]));
            }
            buf.append(')');
        }

        public String toString() {
            StringBuffer buf = new StringBuffer();
            buf.append(overrides[0].getName());
            for (int i = 0; i < overrides.length; ++i) {
                MorC m = overrides[i];
                if (m == null) {
                    break;
                }
                buf.append("\n   ");
                toString(m, buf);
            }
            return buf.toString();
        }
    }

    public static String nameOf(Class c) {
        if (c.isArray()) {
            return nameOf(c.getComponentType()) + "[]";
        }
        String name = c.getName();
        return name.substring(name.lastIndexOf('.') + 1);
    }

    static MorC[] getMorCArray(Constructor[] cons) {
        MorC[] result = new MorC[cons.length];
        for (int i = 0 ; i < cons.length; ++i) {
            result[i] = new MorC(cons[i]);
        }
        return result;
    }

    static MorC[] getMorCArray(Method[] meths) {
        MorC[] result = new MorC[meths.length];
        for (int i = 0 ; i < meths.length; ++i) {
            result[i] = new MorC(meths[i]);
        }
        return result;
    }

    private Map getMethodMap(MorC[] meths) {
        Map result = new TreeMap();
        for (int i = 0; i < meths.length; ++i) {
            MorC m = meths[i];
            String key = m.getName();
            MethodRecord mr = (MethodRecord)result.get(key);
            if (mr == null) {
                mr = new MethodRecord(m);
                result.put(key, mr);
            } else {
                mr.add(m);
            }
        }
        return result;
    }

    private void dumpMethodMap(Map m, PrintWriter pw) {
        Iterator iter = m.entrySet().iterator();
        while (iter.hasNext()) {
            dumpMethodRecord((MethodRecord)((Map.Entry)iter.next()).getValue());
        }
        pw.flush();
    }

    private void dumpMethodRecord(MethodRecord mr) {
        pw.println(mr.toString());
    }

    static Map diffMethodMaps(Map m1, Map m2) {
        // get all the methods in m1 that aren't mentioned in m2 at all
        Map result = (Map)((TreeMap)m1).clone();
        result.keySet().removeAll(m2.keySet());
        return result;
    }

    private Map removeIgnored(String name, Map m1) {
        if (ignore == null) {
            return m1;
        }
        if (name.startsWith(srcPrefix)) {
            name = name.substring(srcPrefix.length());
        }
        name += " "; // to avoid accidental prefix of nested class name

        // prune ignore list to relevant items
        ArrayList il = null;
        for (int i = 0; i < ignore.length; ++i) {
            String s = ignore[i];
            if (s.startsWith(name)) {
                if (il == null) {
                    il = new ArrayList();
                }
                il.add(s);
            }
        }
        if (il == null) {
            return m1;
        }
            
        Map result = new TreeMap(((TreeMap)m1).comparator());
        result.putAll(m1);
        Iterator iter = result.entrySet().iterator();
        loop: while (iter.hasNext()) {
            Map.Entry e = (Map.Entry)iter.next();
            String key = (String)e.getKey();
            for (int i = 0; i < il.size(); ++i) {
                String ig = (String)il.get(i);
                if (ig.indexOf(" " + key) != 0) {
                    iter.remove();
                    continue loop;
                }
            }
        }            
        return result;
    }

    private Set removeIgnored(String name, Set s1) {
        if (ignore == null) {
            return s1;
        }
        if (name.startsWith(srcPrefix)) {
            name = name.substring(srcPrefix.length());
        }
        name += " "; // to avoid accidental prefix of nested class name

        // prune ignore list to relevant items
        ArrayList il = null;
        for (int i = 0; i < ignore.length; ++i) {
            String s = ignore[i];
            if (s.startsWith(name)) {
                if (il == null) {
                    il = new ArrayList();
                }
                il.add(s);
            }
        }
        if (il == null) {
            return s1;
        }
            
        Set result = (Set)((TreeSet)s1).clone();
        Iterator iter = result.iterator();
        loop: while (iter.hasNext()) {
            String key = (String)iter.next();
            String fieldname = key.substring(0, key.indexOf(' '));
            for (int i = 0; i < il.size(); ++i) {
                String ig = (String)il.get(i);
                if (ig.indexOf(" " + fieldname) != 0) {
                    iter.remove();
                    continue loop;
                }
            }
        }            
        return result;
    }

    static final boolean[][] assignmentMap = {
        // bool   char   byte  short    int   long  float double   void
        {  true, false, false, false, false, false, false, false, false }, // boolean
        { false,  true,  true,  true, false, false, false, false, false }, // char
        { false, false,  true, false, false, false, false, false, false }, // byte
        { false, false,  true,  true, false, false, false, false, false }, // short
        { false,  true,  true,  true,  true, false, false, false, false }, // int
        { false,  true,  true,  true,  true,  true, false, false, false }, // long
        { false,  true,  true,  true,  true, false,  true, false, false }, // float
        { false,  true,  true,  true,  true, false,  true,  true, false }, // double
        { false, false, false, false, false, false, false, false,  true }, // void
    };

    static final Class[] prims = {
        boolean.class, char.class, byte.class, short.class,
        int.class, long.class, float.class, double.class, void.class
    };

    static int primIndex(Class cls) {
        for (int i = 0; i < prims.length; ++i) {
            if (cls == prims[i]) {
                return i;
            }
        }
        throw new IllegalStateException("could not find primitive class: " + cls);
    }

    static boolean assignableFrom(Class lhs, Class rhs) {
        if (lhs == rhs) {
            return true;
        }
        if (lhs.isPrimitive()) {
            if (!rhs.isPrimitive()) {
                return false;
            }
            int lhsx = primIndex(lhs);
            int rhsx = primIndex(rhs);
            return assignmentMap[lhsx][rhsx];
        }
        return lhs.isAssignableFrom(rhs);
    }

    private String toString(Field f) {
        StringBuffer buf = new StringBuffer(f.getName());
        int mod = f.getModifiers() & MOD_MASK;
        if (mod != 0) {
            buf.append(" " + Modifier.toString(mod));
        }
        buf.append(" ");
        String n = pairEquivalent(f.getType().getName());
        n = n.substring(n.lastIndexOf('.') + 1);
        buf.append(n);
        return buf.toString();
    }

    private Set getFieldSet(Field[] fs) {
        Set set = new TreeSet();
        for (int i = 0; i < fs.length; ++i) {
            set.add(toString(fs[i]));
        }
        return set;
    }

    static Set diffFieldSets(Set s1, Set s2) {
        Set result = (Set)((TreeSet)s1).clone();
        result.removeAll(s2);
        return result;
    }

    private void dumpFieldSet(Set s, PrintWriter pw) {
        Iterator iter = s.iterator();
        while (iter.hasNext()) {
            pw.println(iter.next());
        }
        pw.flush();
    }

    // given a target string, if it matches the first of one of our pairs, return the second
    // or vice-versa if swap is true
    private String pairEquivalent(String target) {
        for (int i = 0; i < namePairs.length; i += 2) {
            if (swap) {
                if (target.equals(namePairs[i+1])) {
                    return namePairs[i];
                }
            } else {
                if (target.equals(namePairs[i])) {
                    return namePairs[i+1];
                }
            }
        }
        return target;
    }

    private Class pairClassEquivalent(Class target) {
        for (int i = 0; i < classPairs.length; i += 2) {
            if (target.equals(classPairs[i])) {
                return classPairs[i+1];
            }
        }
        return target;
    }

    static final int MOD_MASK = ~(Modifier.FINAL|Modifier.SYNCHRONIZED|
                                  Modifier.VOLATILE|Modifier.TRANSIENT|Modifier.NATIVE);
}
