/**
*******************************************************************************
* Copyright (C) 2004, 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.*;
import java.util.*;

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

    public static final int VERSION = 1;

    // 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;
    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;
    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 static final char SEP = ';';

    // internal state
    private int    info; // information about numeric values packed into an int as 2-bit 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 

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

    /**
     * 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);
	return (info >> (typ*2)) & 0x3;
    }

    /**
     * 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 >> (typ*2)) & 0x3;
	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);
	info &= ~(0x3 << (typ*2));
	info |= (val&0x3) << (typ * 2);
    }

    /**
     * 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) {
	    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;
	}

	for (int i = 0; i < vals.length; ++i) {
	    if (val.equalsIgnoreCase(vals[i])) {
		info &= ~(0x3 << (typ*2));
		info |= i << (typ*2);
		return;
	    }
	}

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

    /**
     * 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);
		}
		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 successfule, 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
     * 255 chars.
     */
    public static String readToken(BufferedReader r) throws IOException {
        char[] buf = new char[256];
        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.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) {
				    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) {
				    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) {
	StringBuffer buf = new StringBuffer();

	// 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.";
	    StringBuffer tbuf = new StringBuffer();
	    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 = STA; i < CAT; ++i) { // include status
	    String s = get(i, false);
	    if (s != null && s.length() > 0) {
		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 (cls.length() > 0) {
		buf.append(cls);
		buf.append('.');
	    }
	    buf.append(name);
	    if (detail) {
		buf.append(' ');
		buf.append(sig);
	    }
	    break;

	case CAT_FIELD:
	    buf.append(xsig);
	    buf.append(' ');
	    buf.append(name);
	    break;

	case CAT_METHOD:
	case CAT_CONSTRUCTOR:
	    int n = xsig.indexOf('(');
	    if (n > 0) {
		buf.append(xsig.substring(0, n));
		buf.append(' ');
	    } else {
		n = 0;
	    }
	    buf.append(name);
	    buf.append(xsig.substring(n));
	    break;
	}

	pw.print(buf.toString());
    }

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

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

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

    private static final String[][] shortNames = {
	{ "DR", "ST", "DP", "OB" },
	{ "PK", "PB", "PT", "PR" },
	{ "NS", "ST" },
	{ "NF", "FN" },
	{ "NS", "SY" },
	{ "NA", "AB" },
	{ "L", "F", "C", "M" },
	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);
    }
}
