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

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

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 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
                BufferedReader br = null;
                try {
                    ArrayList nl = new ArrayList();
                    File f = new File(namelist.substring(1));
                    FileInputStream fis = new FileInputStream(f);
                    InputStreamReader isr = new InputStreamReader(fis);
                    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();
                }
                finally {
                    if (br != null) {
                        try {
                            br.close();
                        } catch (Exception e) {
                            // ignore
                        }
                    }
                }
            } 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
                BufferedReader br = null;
                try {
                    ArrayList nl = new ArrayList();
                    File f = new File(namelist.substring(1));
                    FileInputStream fis = new FileInputStream(f);
                    InputStreamReader isr = new InputStreamReader(fis);
                    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();
                } finally {
                    if (br != null) {
                        try {
                            br.close();
                        } catch (Exception e) {
                            // ignore
                        }
                    }
                }

            } 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);

        if (n1.indexOf("DecimalFormatSymbols") != -1) {
          pw.format("fields in %s: %s%n", n1, set1);
          pw.format("fields in %s: %s%n", n2, set2);
        }

        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);
}
