// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/**
 *******************************************************************************
 * Copyright (C) 2005-2013, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

/**
 * Represents the API information on a doc element.
 */

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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Comparator;

class APIInfo {
    // version id for the format of the APIInfo data

    public static final int VERSION = 2;

    // public keys and values for queries on info

    public static final int STA = 0, STA_DRAFT = 0, STA_STABLE = 1, STA_DEPRECATED = 2,
      STA_OBSOLETE = 3, STA_INTERNAL = 4;
    public static final int VIS = 1, VIS_PACKAGE = 0, VIS_PUBLIC= 1, VIS_PROTECTED = 2,
      VIS_PRIVATE = 3;
    public static final int STK = 2, STK_STATIC = 1;
    public static final int FIN = 3, FIN_FINAL = 1;
    public static final int SYN = 4, SYN_SYNCHRONIZED = 1;
    public static final int ABS = 5, ABS_ABSTRACT = 1;
    public static final int CAT = 6, CAT_CLASS = 0, CAT_FIELD = 1, CAT_CONSTRUCTOR = 2,
      CAT_METHOD = 3, CAT_ENUM = 4, CAT_ENUM_CONSTANT = 5;
    public static final int PAK = 7;
    public static final int CLS = 8;
    public static final int NAM = 9;
    public static final int SIG = 10;
    public static final int EXC = 11;
    public static final int NUM_TYPES = 11;

    // the separator between tokens in the data file
    public int[] masks = { 0x7, 0x3, 0x1, 0x1, 0x1, 0x1, 0x7 };
    public int[] shifts = { 0, 3, 5, 6, 7, 8, 9 };

    public static final char SEP = ';';

    // Internal State

    private int    info;       // information about numeric values packed into an int
                               // as variable-length nibbles
    private String pack = "";  // package
    private String cls  = "";  // enclosing class
    private String name = "";  // name
    private String sig  = "";  // signature, class: inheritance, method: signature,
                               // field: type, const: signature
    private String exc  = "";  // throws
    private String stver = ""; // status version

    private boolean includeStatusVer = false;

    public int hashCode() {
        return (((pack.hashCode() << 3) ^ cls.hashCode()) << 3) ^ name.hashCode();
    }

    public boolean equals(Object rhs) {
        if (rhs == this) return true;
        if (rhs == null) return false;
        try {
            APIInfo that = (APIInfo)rhs;
            return this.info == that.info &&
                this.pack.equals(that.pack) &&
                this.cls.equals(that.cls) &&
                this.name.equals(that.name) &&
                this.sig.equals(that.sig) &&
                this.exc.equals(that.exc) &&
                this.stver.equals(this.stver);
        }
        catch (ClassCastException e) {
            return false;
        }
    }

    public void setDraft() { setType(STA, STA_DRAFT); }
    public void setStable() { setType(STA, STA_STABLE); }
    public void setDeprecated() { setType(STA, STA_DEPRECATED); }
    public void setObsolete() { setType(STA, STA_OBSOLETE); }
    public void setInternal() { setType(STA, STA_INTERNAL); }
    public void setPackage() { setType(VIS, VIS_PACKAGE); }
    public void setPublic() { setType(VIS, VIS_PUBLIC); }
    public void setProtected() { setType(VIS, VIS_PROTECTED); }
    public void setPrivate() { setType(VIS, VIS_PRIVATE); }
    public void setStatic() { setType(STK, STK_STATIC); }
    public void setFinal() { setType(FIN, FIN_FINAL); }
    public void setSynchronized() { setType(SYN, SYN_SYNCHRONIZED); }
    public void setAbstract() { setType(ABS, ABS_ABSTRACT); }
    public void setClass() { setType(CAT, CAT_CLASS); }
    public void setField() { setType(CAT, CAT_FIELD); }
    public void setConstructor() { setType(CAT, CAT_CONSTRUCTOR); }
    public void setMethod() { setType(CAT, CAT_METHOD); }
    public void setEnum() { setType(CAT, CAT_ENUM); }
    public void setEnumConstant() { setType(CAT, CAT_ENUM_CONSTANT); }

    public void setPackage(String val) { setType(PAK, val); }
    public void setClassName(String val) { setType(CLS, val); }
    public void setName(String val) { setType(NAM, val); }
    public void setSignature(String val) { setType(SIG, val); }
    public void setExceptions(String val) { setType(EXC, val); }

    public boolean isDraft() { return getVal(STA) == STA_DRAFT; }
    public boolean isStable() { return getVal(STA) == STA_STABLE; }
    public boolean isDeprecated() { return getVal(STA) == STA_DEPRECATED; }
    public boolean isObsolete() { return getVal(STA) == STA_OBSOLETE; }
    public boolean isInternal() { return getVal(STA) == STA_INTERNAL; }
    public boolean isPackage() { return getVal(VIS) == VIS_PACKAGE; }
    public boolean isPublic() { return getVal(VIS) == VIS_PUBLIC; }
    public boolean isProtected() { return getVal(VIS) == VIS_PROTECTED; }
    public boolean isPrivate() { return getVal(VIS) == VIS_PRIVATE; }
    public boolean isStatic() { return getVal(STK) == STK_STATIC; }
    public boolean isFinal() { return getVal(FIN) == FIN_FINAL; }
    public boolean isSynchronized() { return getVal(SYN) == SYN_SYNCHRONIZED; }
    public boolean isAbstract() { return getVal(ABS) == ABS_ABSTRACT; }
    public boolean isClass() { return getVal(CAT) == CAT_CLASS; }
    public boolean isField() { return getVal(CAT) == CAT_FIELD; }
    public boolean isConstructor() { return getVal(CAT) == CAT_CONSTRUCTOR; }
    public boolean isMethod() { return getVal(CAT) == CAT_METHOD; }
    public boolean isEnum() { return getVal(CAT) == CAT_ENUM; }
    public boolean isEnumConstant() { return getVal(CAT) == CAT_ENUM_CONSTANT; }

    public String getPackageName() { return get(PAK, true); }
    public String getClassName() { return get(CLS, true); }
    public String getName() { return get(NAM, true); }
    public String getSignature() { return get(SIG, true); }
    public String getExceptions() { return get(EXC, true); }

    public void setStatusVersion(String v) { stver = v; }
    public String getStatusVersion() { return stver; }

    /**
     * Return the integer value for the provided type.  The type
     * must be one of the defined type names.  The return value
     * will be one of corresponding values for that type.
     */
    public int getVal(int typ) {
        validateType(typ);
        if (typ >= shifts.length) {
            return 0;
        }
        return (info >>> shifts[typ]) & masks[typ];
    }

    /**
     * Return the string value for the provided type.  The type
     * must be one of the defined type names.  The return value
     * will be one of corresponding values for that type.  Brief
     * should be true for writing data files, false for presenting
     * information to the user.
     */
    public String get(int typ, boolean brief) {
        validateType(typ);
        String[] vals = brief ? shortNames[typ] : names[typ];
        if (vals == null) {
            switch (typ) {
            case PAK: return pack;
            case CLS: return cls;
            case NAM: return name;
            case SIG: return sig;
            case EXC: return exc;
            }
        }
        int val = (info >>> shifts[typ]) & masks[typ];
        return vals[val];
    }

    /**
     * Set the numeric value for the type.  The value should be a
     * value corresponding to the type.  Only the lower two bits
     * of the value are used.
     */
    public void setType(int typ, int val) {
        validateType(typ);
        if (typ < masks.length) {
            info &= ~(masks[typ] << shifts[typ]);
            info |= (val&masks[typ]) << shifts[typ];
        }
    }

    /**
     * Set the string value for the type.  For numeric types,
     * the value should be a string in 'brief' format.  For
     * non-numeric types, the value can be any
     * string.
     */
    private void setType(int typ, String val) {
        validateType(typ);
        String[] vals = shortNames[typ];
        if (vals == null) {
            if (val == null) {
                val = "";
            }
            switch (typ) {
            case PAK: pack = val; break;
            case CLS: cls = val; break;
            case NAM: name = val; break;
            case SIG: sig = val; break;
            case EXC: exc = val; break;
            }
            return;
        }

        // status version
        String version = "";
        if (typ == STA) {
            int idx = val.indexOf('@');
            if (idx != -1) {
                version = val.substring(idx + 1);
                val = val.substring(0, idx);
            }
        }

        for (int i = 0; i < vals.length; ++i) {
            if (val.equalsIgnoreCase(vals[i])) {
                info &= ~(masks[typ] << shifts[typ]);
                info |= i << shifts[typ];
                if (version.length() > 0) {
                    setStatusVersion(version);
                }
                return;
            }
        }

        throw new IllegalArgumentException(
            "unrecognized value '" + val + "' for type '" + typeNames[typ] + "'");
    }

    /**
     * Enable status version included in input/output
     */
    public void includeStatusVersion(boolean include) {
        includeStatusVer = include;
    }

    /**
     * Write the information out as a single line in brief format.
     * If there are IO errors, throws a RuntimeException.
     */
    public void writeln(BufferedWriter w) {
        try {
            for (int i = 0; i < NUM_TYPES; ++i) {
                String s = get(i, true);
                if (s != null) {
                    w.write(s);
                }
                if (includeStatusVer && i == STA) {
                    String ver = getStatusVersion();
                    if (ver.length() > 0) {
                        w.write("@");
                        w.write(getStatusVersion());
                    }
                }
                w.write(SEP);
            }
            w.newLine();
        }
        catch (IOException e) {
            RuntimeException re = new RuntimeException("IO Error");
            re.initCause(e);
            throw re;
        }
    }

    /**
     * Read a record from the input and initialize this APIInfo.
     * Return true if successful, false if EOF, otherwise throw
     * a RuntimeException.
     */
    public boolean read(BufferedReader r) {
        int i = 0;
        try {
            for (; i < NUM_TYPES; ++i) {
                setType(i, readToken(r));
            }
            r.readLine(); // swallow line end sequence
        }
        catch (IOException e) {
            if (i == 0) { // assume if first read returns error, we have reached end of input
                return false;
            }
            RuntimeException re = new RuntimeException("IO Error");
            re.initCause(e);
            throw re;
        }

        return true;
    }

    /**
     * Read one token from input, which should have been written by
     * APIInfo.  Throws IOException if EOF is encountered before the
     * token is complete (i.e. before the separator character is
     * encountered) or if the token exceeds the maximum length of
     * 511 chars.
     */
    public static String readToken(BufferedReader r) throws IOException {
        char[] buf = new char[512];
        int i = 0;
        for (; i < buf.length; ++i) {
            int c = r.read();
            if (c == -1) {
                throw new IOException("unexpected EOF");
            } else if (c == SEP) {
                break;
            }
            buf[i] = (char)c;
        }
        if (i == buf.length) {
            throw new IOException("unterminated token" + new String(buf));
        }

        return new String(buf, 0, i);
    }

    /**
     * The default comparator for APIInfo.  This compares packages, class/name
     * (as the info represents a class or other object), category, name,
     * and signature.
     */
    public static Comparator defaultComparator() {
        final Comparator c = new Comparator() {
                public int compare(Object lhs, Object rhs) {
                    APIInfo lhi = (APIInfo)lhs;
                    APIInfo rhi = (APIInfo)rhs;
                    int result = lhi.pack.compareTo(rhi.pack);
                    if (result == 0) {
                        result = (lhi.getVal(CAT) == CAT_CLASS || lhi.getVal(CAT) == CAT_ENUM ? lhi.name : lhi.cls)
                            .compareTo(rhi.getVal(CAT) == CAT_CLASS || rhi.getVal(CAT) == CAT_ENUM ? rhi.name : rhi.cls);
                        if (result == 0) {
                            result = lhi.getVal(CAT)- rhi.getVal(CAT);
                            if (result == 0) {
                                result = lhi.name.compareTo(rhi.name);
                                if (result == 0) {
                                    result = lhi.sig.compareTo(rhi.sig);
                                }
                            }
                        }
                    }
                    return result;
                }
            };
        return c;
    }

    /**
     * This compares two APIInfos by package, class/name, category, name, and then if
     * the APIInfo does not represent a class, by signature.  The difference between
     * this and the default comparator is that APIInfos representing classes are considered
     * equal regardless of their signatures (which represent inheritance for classes).
     */
    public static Comparator changedComparator() {
        final Comparator c = new Comparator() {
                public int compare(Object lhs, Object rhs) {
                    APIInfo lhi = (APIInfo)lhs;
                    APIInfo rhi = (APIInfo)rhs;
                    int result = lhi.pack.compareTo(rhi.pack);
                    if (result == 0) {
                        result = (lhi.getVal(CAT) == CAT_CLASS ? lhi.name : lhi.cls)
                            .compareTo(rhi.getVal(CAT) == CAT_CLASS ? rhi.name : rhi.cls);
                        if (result == 0) {
                            result = lhi.getVal(CAT)- rhi.getVal(CAT);
                            if (result == 0) {
                                result = lhi.name.compareTo(rhi.name);
                                if (result == 0 && lhi.getVal(CAT) != CAT_CLASS) {
                                    // signature change on fields ignored
                                    if (lhi.getVal(CAT) != CAT_FIELD) {
                                        result = lhi.sig.compareTo(rhi.sig);
                                    }
                                }
                            }
                        }
                    }
                    return result;
                }
            };
        return c;
    }

    /**
     * This compares two APIInfos by package, then sorts classes before non-classes, then
     * by class/name, category, name, and signature.
     */
    public static Comparator classFirstComparator() {
        final Comparator c = new Comparator() {
                public int compare(Object lhs, Object rhs) {
                    APIInfo lhi = (APIInfo)lhs;
                    APIInfo rhi = (APIInfo)rhs;
                    int result = lhi.pack.compareTo(rhi.pack);
                    if (result == 0) {
                        boolean lcls = lhi.getVal(CAT) == CAT_CLASS;
                        boolean rcls = rhi.getVal(CAT) == CAT_CLASS;
                        result = lcls == rcls ? 0 : (lcls ? -1 : 1);
                        if (result == 0) {
                            result = (lcls ? lhi.name : lhi.cls).compareTo(
                                rcls ? rhi.name : rhi.cls);
                            if (result == 0) {
                                result = lhi.getVal(CAT)- rhi.getVal(CAT);
                                if (result == 0) {
                                    result = lhi.name.compareTo(rhi.name);
                                    if (result == 0 && !lcls) {
                                        result = lhi.sig.compareTo(rhi.sig);
                                    }
                                }
                            }
                        }
                    }
                    return result;
                }
            };
        return c;
    }

    /**
     * Write the data in report format.
     */
    public void print(PrintWriter pw, boolean detail, boolean html) {
        print(pw, detail, html, true);
    }

    public void print(PrintWriter pw, boolean detail, boolean html, boolean withStatus) {
        StringBuilder buf = new StringBuilder();
        format(buf, detail, html, withStatus);
        pw.print(buf.toString());
    }

    public void format(StringBuilder buf, boolean detail, boolean html, boolean withStatus) {
        // remove all occurrences of icu packages from the param string
        // fortunately, all the packages have 4 chars (lang, math, text, util).
        String xsig = sig;
        if (!detail) {
            final String ICUPACK = "com.ibm.icu.";
            StringBuilder tbuf = new StringBuilder();
            for (int i = 0; i < sig.length();) {
                int n = sig.indexOf(ICUPACK, i);
                if (n == -1) {
                    tbuf.append(sig.substring(i));
                    break;
                }
                tbuf.append(sig.substring(i, n));
                i = n + ICUPACK.length() + 5; // trailing 'xxxx.'
            }
            xsig = tbuf.toString();
        }

        // construct signature
        for (int i = (withStatus ? STA : VIS) ; i < CAT; ++i) { // include status
            String s = get(i, false);
            if (s != null && s.length() > 0) {
                if (html) {
                    s = s.trim();
                    if (i == STA) {
                        String color = null;
                        if (s.startsWith("(internal)")) {
                            color = "red";
                        } else if (s.startsWith("(draft)")) {
                            color = "orange";
                        } else if (s.startsWith("(stable)")) {
                            color = "green";
                        } else if (s.startsWith("(deprecated)")) {
                            color = "gray";
                        }
                        if (color != null) {
                            s = "<span style='color:" + color + "'>" + prepText(s, html) + "</span>";
                        }
                    }
                }
                buf.append(s);
                buf.append(' ');
            }
        }

        int val = getVal(CAT);
        switch (val) {
        case CAT_CLASS:
            if (sig.indexOf("extends") == -1) {
                buf.append("interface ");
            } else {
                buf.append("class ");
            }
            if (html) {
                buf.append("<i>");
            }
            if (cls.length() > 0) {
                buf.append(prepText(cls, html));
                buf.append('.');
            }
            buf.append(prepText(name, html));
            if (html) {
                buf.append("</i>");
            }
            if (detail) {
                buf.append(' ');
                buf.append(prepText(sig, html));
            }
            break;

        case CAT_ENUM:
            buf.append("enum ");
            if (html) {
                buf.append("<i>");
            }
            if (cls.length() > 0) {
                buf.append(prepText(cls, html));
                buf.append('.');
            }
            buf.append(prepText(name, html));
            if (html) {
                buf.append("</i>");
            }
            if (detail) {
                buf.append(' ');
                buf.append(prepText(sig, html));
            }
            break;

        case CAT_FIELD:
        case CAT_ENUM_CONSTANT:
            buf.append(prepText(xsig, html));
            buf.append(' ');
            buf.append(prepText(name, html));
            break;

        case CAT_METHOD:
        case CAT_CONSTRUCTOR:
            int n = xsig.indexOf('(');
            if (n > 0) {
                buf.append(prepText(xsig.substring(0, n), html));
                buf.append(' ');
            } else {
                n = 0;
            }
            if (html) {
                buf.append("<i>" + prepText(name, html) + "</i>");
            } else {
                buf.append(name);
            }
            buf.append(prepText(xsig.substring(n), html));
            break;
        }
    }

    private static String prepText(String text, boolean html) {
        if (html && (text.indexOf('<') >= 0 || text.indexOf('>') >= 0)) {
            StringBuilder buf = new StringBuilder();
            for (int i = 0; i < text.length(); i++) {
                char c = text.charAt(i);
                if (c == '<') {
                    buf.append("&lt;");
                } else if (c == '>') {
                    buf.append("&gt;");
                } else {
                    buf.append(c);
                }
            }
            text = buf.toString();
        }
        return text;
    }

    public void println(PrintWriter pw, boolean detail, boolean html) {
        print(pw, detail, html);
        pw.println();
    }

    private static final String[] typeNames = {
        "status", "visibility", "static", "final", "synchronized",
        "abstract", "category", "package", "class", "name", "signature"
    };

    public static final String getTypeValName(int typ, int val) {
        try {
            return names[typ][val];
        }
        catch (Exception e) {
            return "";
        }
    }

    private static final String[][] names = {
        { "(draft)     ", "(stable)    ", "(deprecated)", "(obsolete)  ", "*internal*  " },
        { "package", "public", "protected", "private" },
        { "", "static" },
        { "", "final" },
        { "", "synchronized" },
        { "", "abstract" },
        { "class", "field", "constructor", "method", "enum", "enum constant"  },
        null,
        null,
        null,
        null,
        null
    };

    private static final String[][] shortNames = {
        { "DR", "ST", "DP", "OB", "IN" },
        { "PK", "PB", "PT", "PR" },
        { "NS", "ST" },
        { "NF", "FN" },
        { "NS", "SY" },
        { "NA", "AB" },
        { "L", "F", "C", "M", "E", "K" },
        null,
        null,
        null,
        null,
        null
    };

    private static void validateType(int typ) {
        if (typ < 0 || typ > NUM_TYPES) {
            throw new IllegalArgumentException("bad type index: " + typ);
        }
    }

    public String toString() {
        return get(NAM, true);
    }
}
