/**
*******************************************************************************
* Copyright (C) 2004-2005, 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) {
                    if (val == APIInfo.STA_DEPRECATED) {
                        // ok to have both a 'standard' tag and deprecated
                        return;
                    } else if (res != APIInfo.STA_DEPRECATED) {
                        // if already not deprecated, this is an error
                        throw new RuntimeException("bad doc: " + doc + " old: " + res + " new: " + val); 
                    }
                }
                // ok to replace with new tag
                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;
    }
}
