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

/**
 * Generate a list of ICU's public APIs, sorted by qualified name and signature
 * public APIs are all non-internal, non-package apis in com.ibm.icu.[lang|math|text|util].
 * For each API, list
 * - public, package, protected, or private (PB PK PT PR)
 * - static or non-static (STK NST)
 * - final or non-final (FN NF)
 * - synchronized or non-synchronized (SYN NSY)
 * - stable, draft, deprecated, obsolete (ST DR DP OB)
 * - abstract or non-abstract (AB NA)
 * - constructor, member, field (C M F)
 *
 * Requires JDK 1.4.2 or later
 * 
 * Sample compilation:
 * c:/doug/java/jdk1.4.2/build/windows-i586/bin/javac *.java
 *
 * Sample execution
 * c:/j2sdk1.4.2/bin/javadoc
 *   -classpath c:/jd2sk1.4.2/lib/tools.jar 
 *   -doclet com.ibm.icu.dev.tool.docs.GatherAPIData
 *   -docletpath c:/doug/cvsproj/icu4j/src 
 *   -sourcepath c:/doug/cvsproj/icu4j/src 
 *   -name "ICU4J 3.0"
 *   -output icu4j30.api
 *   -gzip
 *   -source 1.4
 *   com.ibm.icu.lang com.ibm.icu.math com.ibm.icu.text com.ibm.icu.util
 *
 * todo: separate generation of data files (which requires taglet) from 
 * comparison and report generation (which does not require it)
 * todo: provide command-line control of filters of which subclasses/packages to process
 * todo: record full inheritance heirarchy, not just immediate inheritance 
 * todo: allow for aliasing comparisons (force (pkg.)*class to be treated as though it 
 * were in a different pkg/class heirarchy (facilitates comparison of icu4j and java)
 */

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

// standard release sdk won't work, need internal build to get access to javadoc
import com.sun.javadoc.*;
import java.io.*;
import java.util.*;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class GatherAPIData {
    RootDoc root;
    TreeSet results;
    String srcName = "Current"; // default source name
    String output; // name of output file to write
    String base; // strip this prefix
    String filter; // filter classes by name
    boolean zip;
    boolean gzip;

    public static int optionLength(String option) {
        if (option.equals("-name")) {
            return 2;
        } else if (option.equals("-output")) {
            return 2;
	} else if (option.equals("-base")) {
	    return 2;
	} else if (option.equals("-filter")) {
	    return 2;
	} else if (option.equals("-zip")) {
	    return 1;
	} else if (option.equals("-gzip")) {
	    return 1;
	}
        return 0;
    }

    public static boolean start(RootDoc root) {
        return new GatherAPIData(root).run();
    }

    GatherAPIData(RootDoc root) {
        this.root = root;

        String[][] options = root.options();
        for (int i = 0; i < options.length; ++i) {
            String opt = options[i][0];
            if (opt.equals("-name")) {
                this.srcName = options[i][1];
            } else if (opt.equals("-output")) {
                this.output = options[i][1];
            } else if (opt.equals("-base")) {
		this.base = options[i][1]; // should not include '.'
	    } else if (opt.equals("-filter")) {
		this.filter = options[i][1];
	    } else if (opt.equals("-zip")) {
		this.zip = true;
	    } else if (opt.equals("-gzip")) {
		this.gzip = true;
	    }
        }

        results = new TreeSet(APIInfo.defaultComparator());
    }

    private boolean run() {
        doDocs(root.classes());

        OutputStream os = System.out;
        if (output != null) {
            try {
		if (zip) {
		    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output + ".zip"));
		    zos.putNextEntry(new ZipEntry(output));
		    os = zos;
		} else if (gzip) {
		    os = new GZIPOutputStream(new FileOutputStream(output + ".gz"));
		} else {
		    os = new FileOutputStream(output);
		}
            }
            catch (IOException e) {
                RuntimeException re = new RuntimeException(e.getMessage());
                re.initCause(e);
                throw re;
            }
        }

        BufferedWriter bw = null;
        try {
            OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
            bw = new BufferedWriter(osw);

	    // writing data file
	    bw.write(String.valueOf(APIInfo.VERSION) + APIInfo.SEP); // header version
	    bw.write(srcName + APIInfo.SEP); // source name
	    bw.write((base == null ? "" : base) + APIInfo.SEP); // base
	    bw.newLine();
	    writeResults(results, bw);
	    bw.close(); // should flush, close all, etc
//  	    if (zip) {
//  		((ZipOutputStream)os).finish();
//  	    }
        } catch (IOException e) {
            try { bw.close(); } catch (IOException e2) {}
            RuntimeException re = new RuntimeException("write error: " + e.getMessage());
            re.initCause(e);
            throw re;
        }

        return false;
    }

    private void doDocs(ProgramElementDoc[] docs) {
        if (docs != null && docs.length > 0) {
            for (int i = 0; i < docs.length; ++i) {
                doDoc(docs[i]);
            }
        }
    }

    private void doDoc(ProgramElementDoc doc) {
        if (ignore(doc)) return;

        if (doc.isClass() || doc.isInterface()) {
            ClassDoc cdoc = (ClassDoc)doc;
            doDocs(cdoc.fields());
            doDocs(cdoc.constructors());
            doDocs(cdoc.methods());
            doDocs(cdoc.innerClasses());
        }

	APIInfo info = createInfo(doc);
	if (info != null) {
	    results.add(info);
	}
    }

    private boolean ignore(ProgramElementDoc doc) {
        if (doc == null) return true;
        if (doc.isPrivate() || doc.isPackagePrivate()) return true;
        if (doc instanceof ConstructorDoc && ((ConstructorDoc)doc).isSynthetic()) return true;
        if (doc.qualifiedName().indexOf(".misc") != -1) { System.out.println("misc: " + doc.qualifiedName()); return true; }
        Tag[] tags = doc.tags();
        for (int i = 0; i < tags.length; ++i) {
            if (tagKindIndex(tags[i].kind()) == INTERNAL) return true;
        }

        return false;
    }

    private static void writeResults(Collection c, BufferedWriter w) {
        Iterator iter = c.iterator();
        while (iter.hasNext()) {
            APIInfo info = (APIInfo)iter.next();
	    info.writeln(w);
        }
    }

    private String trimBase(String arg) {
	if (base != null) {
	    for (int n = arg.indexOf(base); n != -1; n = arg.indexOf(base, n)) {
		arg = arg.substring(0, n) + arg.substring(n+base.length());
	    }
	}
	return arg;
    }

    public APIInfo createInfo(ProgramElementDoc doc) {

	// Doc. name
	// Doc. isField, isMethod, isConstructor, isClass, isInterface
	// ProgramElementDoc. containingClass, containingPackage
	// ProgramElementDoc. isPublic, isProtected, isPrivate, isPackagePrivate
	// ProgramElementDoc. isStatic, isFinal
	// MemberDoc.isSynthetic
	// ExecutableMemberDoc isSynchronized, signature
	// Type.toString() // e.g. "String[][]"
	// ClassDoc.isAbstract, superClass, interfaces, fields, methods, constructors, innerClasses
	// FieldDoc type
	// ConstructorDoc qualifiedName
	// MethodDoc isAbstract, returnType

	APIInfo info = new APIInfo();
            
	// status
	info.setType(APIInfo.STA, tagStatus(doc));

	// visibility
	if (doc.isPublic()) {
	    info.setPublic();
	} else if (doc.isProtected()) {
	    info.setProtected();
	} else if (doc.isPrivate()) {
	    info.setPrivate();
	} else {
	    // default is package
	}

	// static
	if (doc.isStatic()) {
	    info.setStatic();
	} else {
	    // default is non-static
	}

	// final
	if (doc.isFinal()) {
	    info.setFinal();
	} else {
	    // default is non-final
	}

	// type
	if (doc.isField()) {
	    info.setField();
	} else if (doc.isMethod()) {
	    info.setMethod();
	} else if (doc.isConstructor()) {
	    info.setConstructor();
	} else if (doc.isClass() || doc.isInterface()) {
	    info.setClass();
	}

	info.setPackage(trimBase(doc.containingPackage().name()));
	info.setClassName((doc.isClass() || doc.isInterface() || (doc.containingClass() == null)) 
			  ? "" 
			  : trimBase(doc.containingClass().name()));
	info.setName(trimBase(doc.name()));
	
	if (doc instanceof FieldDoc) {
	    FieldDoc fdoc = (FieldDoc)doc;
	    info.setSignature(trimBase(fdoc.type().toString()));
	} else if (doc instanceof ClassDoc) {
	    ClassDoc cdoc = (ClassDoc)doc;

	    if (cdoc.isClass() && cdoc.isAbstract()) { // interfaces are abstract by default, don't mark them as abstract
		info.setAbstract();
	    }

	    StringBuffer buf = new StringBuffer();
	    if (cdoc.isClass()) {
		buf.append("extends ");
		buf.append(cdoc.superclass().qualifiedName());
	    }
	    ClassDoc[] imp = cdoc.interfaces();
	    if (imp != null && imp.length > 0) {
		if (buf.length() > 0) {
		    buf.append(" ");
		}
		buf.append("implements");
		for (int i = 0; i < imp.length; ++i) {
		    if (i != 0) {
			buf.append(",");
		    }
		    buf.append(" ");
		    buf.append(imp[i].qualifiedName());
		}
	    }
	    info.setSignature(trimBase(buf.toString()));
	} else {
	    ExecutableMemberDoc emdoc = (ExecutableMemberDoc)doc;
	    if (emdoc.isSynchronized()) {
		info.setSynchronized();
	    }

	    if (doc instanceof MethodDoc) {
		MethodDoc mdoc = (MethodDoc)doc;
		if (mdoc.isAbstract()) {
		    info.setAbstract();
		}
		info.setSignature(trimBase(mdoc.returnType().toString() + emdoc.signature()));
	    } else {
		// constructor
		info.setSignature(trimBase(emdoc.signature()));
	    }
	}

	return info;
    }

    private static int tagStatus(final Doc doc) {
        class Result {
            int res = -1;
            void set(int val) { if (res != -1) throw new RuntimeException("bad doc: " + doc); res = val; }
            int get() {
                if (res == -1) {
                    System.err.println("warning: no tag for " + doc);
                    return 0;
                }
                return res;
            }
        };

        Tag[] tags = doc.tags();
        Result result = new Result();
        for (int i = 0; i < tags.length; ++i) {
            Tag tag = tags[i];

            String kind = tag.kind();
            int ix = tagKindIndex(kind);

            switch (ix) {
            case INTERNAL:
                result.set(-2);
                break;

            case DRAFT:
                result.set(APIInfo.STA_DRAFT);
                break;

            case STABLE:
                result.set(APIInfo.STA_STABLE);
                break;

            case DEPRECATED:
                result.set(APIInfo.STA_DEPRECATED);
                break;

            case OBSOLETE:
                result.set(APIInfo.STA_OBSOLETE);
                break;

            case SINCE:
            case EXCEPTION:
            case VERSION:
            case UNKNOWN:
            case AUTHOR:
            case SEE:
            case PARAM:
            case RETURN:
            case THROWS:
            case SERIAL:
                break;

            default:
                throw new RuntimeException("unknown index " + ix + " for tag: " + kind);
            }
        }

        return result.get();
    }

    private static final int UNKNOWN = -1;
    private static final int INTERNAL = 0;
    private static final int DRAFT = 1;
    private static final int STABLE = 2;
    private static final int SINCE = 3;
    private static final int DEPRECATED = 4;
    private static final int AUTHOR = 5;
    private static final int SEE = 6;
    private static final int VERSION = 7;
    private static final int PARAM = 8;
    private static final int RETURN = 9;
    private static final int THROWS = 10;
    private static final int OBSOLETE = 11;
    private static final int EXCEPTION = 12;
    private static final int SERIAL = 13;

    private static int tagKindIndex(String kind) {
        final String[] tagKinds = {
            "@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see", "@version",
            "@param", "@return", "@throws", "@obsolete", "@exception", "@serial"
        };

        for (int i = 0; i < tagKinds.length; ++i) {
            if (kind.equals(tagKinds[i])) {
                return i;
            }
        }
        return UNKNOWN;
    }
}
