package jdiff;

import java.io.*;
import java.util.*;

/**
 * The internal representation of an API.
 *
 * RootDoc could have been used for representing this, but
 * you cannot serialize a RootDoc object - see
 *  https://developer.java.sun.com/developer/bugParade/bugs/4125581.html
 * You might be able use Javadoc.Main() to create another RootDoc, but the
 * methods are package private. You can run javadoc in J2SE1.4, see:
 *  https://java.sun.com/j2se/1.4/docs/tooldocs/javadoc/standard-doclet.html#runningprogrammatically
 * but you still can't get the RootDoc object.
 *
 * The advantage of writing out an XML representation of each API is that
 * later runs of JDiff don't have to have Javadoc scan all the files again,
 * a possibly lengthy process. XML also permits other source code in
 * languages other than Java to be scanned to produce XML, and then versions
 * of JDiff can be used to create documents describing the difference in those
 * APIs.
 *
 * See the file LICENSE.txt for copyright details.
 * @author Matthew Doar, mdoar@pobox.com
 */
public class API {

    /** 
     * The list of all the top-level packages. 
     * Each package contains classes, each class contains members, and so on.
     */
    public List packages_; // PackageAPI[]

    /** 
     * The list of all the classes. 
     * This is used to generate the methods and fields which are inherited,
     * rather than storing them in the XML file.
     */
    public Hashtable classes_;

    /** 
     * The String which identifies this API, e.g. &quotSuperProduct 1.3&quot;.
     */
    public String name_ = null;

    /** The current package being added to during parsing. */
    public PackageAPI currPkg_ = null;
    /** The current class being added to during parsing. */
    public ClassAPI currClass_ = null;
    /** The current constructor being added to during parsing. */
    public ConstructorAPI currCtor_ = null;
    /** The current method being added to during parsing. */
    public MethodAPI currMethod_ = null;
    /** The current field being added to during parsing. */
    public FieldAPI currField_ = null;

    /** Default constructor. */
    public API() {
        packages_ = new ArrayList(); //PackageAPI[]
        classes_ = new Hashtable(); //ClassAPI
    }   
  
//
// Methods to display the contents of an API object.
//

    /** Amount by which to increment each indentation. */
    public static final int indentInc = 2;

    /** Display the contents of the API object. */
    public void dump() {
        int indent = 0;
        Iterator iter = packages_.iterator();
        while (iter.hasNext()) {
            dumpPackage((PackageAPI)(iter.next()), indent);
        }
    }

    /** 
     * Display the contents of a PackageAPI object.
     *
     * @param pkg The given PackageAPI object.
     * @param indent The number of spaces to indent the output.
     */
    public void dumpPackage(PackageAPI pkg, int indent) {
        for (int i = 0; i < indent; i++) System.out.print(" ");
        System.out.println("Package Name: " + pkg.name_);
        Iterator iter = pkg.classes_.iterator();
        while (iter.hasNext()) {
            dumpClass((ClassAPI)(iter.next()), indent + indentInc);
        }
        // Display documentation
        if (pkg.doc_ != null) {
            System.out.print("Package doc block:");
            System.out.println("\"" + pkg.doc_ + "\"");
        }
    }

    /** 
     * Display the contents of a ClassAPI object.
     *
     * @param c The given ClassAPI object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpClass(ClassAPI c, int indent) {
        for (int i = 0; i < indent; i++) System.out.print(" ");
        if (c.isInterface_)
            System.out.println("Interface name: " + c.name_);
        else
            System.out.println("Class Name: " + c.name_);
        if (c.extends_ != null) {
            for (int i = 0; i < indent; i++) System.out.print(" ");
            System.out.println("Extends: " + c.extends_);
        }
        if (c.implements_.size() != 0) {
            for (int i = 0; i < indent; i++) System.out.print(" ");
            System.out.println("Implements: ");
            Iterator iter = c.implements_.iterator();
            while (iter.hasNext()) {
                String interfaceImpl = (String)(iter.next());
                for (int i = 0; i < indent + 2; i++) System.out.print(" ");
                System.out.println("  " + interfaceImpl);
            }
        }
        // Dump modifiers specific to a class
        if (c.isAbstract_)
            System.out.print("abstract ");
        // Dump modifiers common to all
        dumpModifiers(c.modifiers_, indent);
        // Dump ctors
        Iterator iter = c.ctors_.iterator();
        while (iter.hasNext()) {
            dumpCtor((ConstructorAPI)(iter.next()), indent + indentInc);
        }
        // Dump methods
        iter = c.methods_.iterator();
        while (iter.hasNext()) {
            dumpMethod((MethodAPI)(iter.next()), indent + indentInc);
        }
        // Dump fields
        iter = c.fields_.iterator();
        while (iter.hasNext()) {
            dumpField((FieldAPI)(iter.next()), indent + indentInc);
        }
        // Display documentation
        if (c.doc_ != null) {
            System.out.print("Class doc block:");
            System.out.println("\"" + c.doc_ + "\"");
        } else
            System.out.println();
    }

    /** 
     * Display the contents of the Modifiers object.
     *
     * @param c The given Modifiers object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpModifiers(Modifiers m, int indent) {
        for (int i = 0; i < indent; i++) System.out.print(" ");
        if (m.isStatic)
            System.out.print("static ");
        if (m.isFinal)
            System.out.print("final ");
        if (m.visibility != null)
            System.out.print("visibility = " + m.visibility + " ");
        // Flush the line
        System.out.println();
    }

    /** 
     * Display the contents of a constructor.
     *
     * @param c The given constructor object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpCtor(ConstructorAPI c, int indent) {
        for (int i = 0; i < indent; i++) System.out.print(" ");
        System.out.println("Ctor type: " + c.getSignature());
        // Display exceptions 
        System.out.print("exceptions: " + c.exceptions_ + " ");
        // Dump modifiers common to all
        dumpModifiers(c.modifiers_, indent);
        // Display documentation
        if (c.doc_ != null) {
            System.out.print("Ctor doc block:");
            System.out.println("\"" + c.doc_ + "\"");
        }
    }

    /** 
     * Display the contents of a MethodAPI object.
     *
     * @param m The given MethodAPI object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpMethod(MethodAPI m, int indent) {
        if (m.inheritedFrom_ != null)
            return;
        for (int i = 0; i < indent; i++) System.out.print(" ");
        System.out.print("Method Name: " + m.name_);
        if (m.inheritedFrom_ != null)
            System.out.println(", inherited from: " + m.inheritedFrom_);
        if (m.returnType_ != null)
            System.out.println(", return type: " + m.returnType_);
        else
            System.out.println();
        // Dump modifiers specific to a method
        if (m.isAbstract_)
            System.out.print("abstract ");
        if (m.isNative_)
            System.out.print("native ");
        if (m.isSynchronized_)
            System.out.print("synchronized ");
        // Display exceptions 
        System.out.print("exceptions: " + m.exceptions_ + " ");
        // Dump modifiers common to all
        dumpModifiers(m.modifiers_, indent);
      
        Iterator iter = m.params_.iterator();
        while (iter.hasNext()) {
            dumpParam((ParamAPI)(iter.next()), indent + indentInc);
        }
        // Display documentation
        if (m.doc_ != null) {
            System.out.print("Method doc block:");
            System.out.println("\"" + m.doc_ + "\"");
        }
    }

    /** 
     * Display the contents of a field.
     * Does not show inherited fields.
     *
     * @param f The given field object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpField(FieldAPI f, int indent) {
        if (f.inheritedFrom_ != null)
            return;
        for (int i = 0; i < indent; i++) System.out.print(" ");
        System.out.println("Field Name: " + f.name_ + ", type: " + f.type_);
        if (f.inheritedFrom_ != null)
            System.out.println(", inherited from: " + f.inheritedFrom_);
        if (f.isTransient_)
            System.out.print("transient ");
        if (f.isVolatile_)
            System.out.print("volatile ");
        // Dump modifiers common to all
        dumpModifiers(f.modifiers_, indent);
        // Display documentation
        if (f.doc_ != null)
            System.out.print("Field doc block:");
            System.out.println("\"" + f.doc_ + "\"");
    }

    /** 
     * Display the contents of a parameter.
     *
     * @param p The given parameter object.
     * @param indent The number of spaces to indent the output.
     */
    public static void dumpParam(ParamAPI p, int indent) {
        for (int i = 0; i < indent; i++) System.out.print(" ");
        System.out.println("Param Name: " + p.name_ + ", type: " + p.type_);
    }

    /** 
     * Convert all HTML tags to text by placing them inside a CDATA element.
     * Characters still have to be valid Unicode characters as defined by the 
     * parser.
     */
    public static String stuffHTMLTags(String htmlText) {
        if (htmlText.indexOf("]]>") != -1) {
            System.out.println("Warning: illegal string ]]> found in text. Ignoring the comment.");
            return "";
        }
        return "<![CDATA[" + htmlText + "]]>";
    }

    /**
     * Convert all HTML tags to text by stuffing text into the HTML tag
     * to stop it being an HTML or XML tag. E.g. &quot;<code>foo</code>&quot;
     * becomes &quot;lEsS_tHaNcode>foolEsS_tHaN/code>&quot;. Replace all &lt; 
     * characters
     * with the string "lEsS_tHaN". Also replace &amp; character with the  
     * string "aNd_cHaR" to avoid text entities. Also replace &quot; 
     * character with the  
     * string "qUoTe_cHaR".
     */
    public static String hideHTMLTags(String htmlText) {
        StringBuffer sb = new StringBuffer(htmlText);
        int i = 0;
        while (i < sb.length()) {
            if (sb.charAt(i) == '<') {
                sb.setCharAt(i ,'l');
                sb.insert(i+1, "EsS_tHaN");
            } else if (sb.charAt(i) == '&') {
                sb.setCharAt(i ,'a');
                sb.insert(i+1, "Nd_cHaR");
            } else if (sb.charAt(i) == '"') {
                sb.setCharAt(i ,'q');
                sb.insert(i+1, "uote_cHaR");
            }
            i++;
        }
        return sb.toString();
    }

    /** 
     * Convert text with stuffed HTML tags ("lEsS_tHaN", etc) into HTML text.
     */
    public static String showHTMLTags(String text) {
        StringBuffer sb = new StringBuffer(text);
        StringBuffer res = new StringBuffer();
        int len = sb.length();
        res.setLength(len);
        int i = 0;
        int resIdx = 0;
        while (i < len) {
            char c = sb.charAt(i);
            if (len - i > 8 && c == 'l' && 
                sb.charAt(i+1) == 'E' &&
                sb.charAt(i+2) == 's' &&
                sb.charAt(i+3) == 'S' &&
                sb.charAt(i+4) == '_' &&
                sb.charAt(i+5) == 't' &&
                sb.charAt(i+6) == 'H' &&
                sb.charAt(i+7) == 'a' &&
                sb.charAt(i+8) == 'N') {
                res.setCharAt(resIdx ,'<');
                i += 8;
            } else if (len - i > 9 && c == 'q' && 
                sb.charAt(i+1) == 'U' &&
                sb.charAt(i+2) == 'o' &&
                sb.charAt(i+3) == 'T' &&
                sb.charAt(i+4) == 'e' &&
                sb.charAt(i+5) == '_' &&
                sb.charAt(i+6) == 'c' &&
                sb.charAt(i+7) == 'H' &&
                sb.charAt(i+8) == 'a' &&
                sb.charAt(i+9) == 'R') {
                res.setCharAt(resIdx ,'"');
                i += 9;
            } else if (len - i > 7 && c == 'a' && 
                sb.charAt(i+1) == 'N' &&
                sb.charAt(i+2) == 'd' &&
                sb.charAt(i+3) == '_' &&
                sb.charAt(i+4) == 'c' &&
                sb.charAt(i+5) == 'H' &&
                sb.charAt(i+6) == 'a' &&
                sb.charAt(i+7) == 'R') {
                res.setCharAt(resIdx ,'&');
                i += 7;
            } else {
                res.setCharAt(resIdx, c);
            }
            i++;
            resIdx++;
        }
        res.setLength(resIdx);
        return res.toString();
    }

    /** 
     * <b>NOT USED</b>. 
     *
     * Replace all instances of <p> with <p/>. Just for the small number
     * of HMTL tags which don't require a matching end tag.
     * Also make HTML conform to the simple HTML requirements such as 
     * no double hyphens. Double hyphens are replaced by - and the character
     * entity for a hyphen.
     *
     * Cases where this fails and has to be corrected in the XML by hand: 
     *  Attributes' values missing their double quotes , e.g. size=-2
     *  Mangled HTML tags e.g. &lt;ttt> 
     *
     * <p><b>NOT USED</b>. There is often too much bad HTML in
     * doc blocks to try to handle every case correctly. Better just to
     * stuff the *lt; and &amp: characters with stuffHTMLTags(). Though
     * the resulting XML is not as elegant, it does the job with less
     * intervention by the user.
     */
    public static String convertHTMLTagsToXHTML(String htmlText) {
        StringBuffer sb = new StringBuffer(htmlText);
        int i = 0;
        boolean inTag = false;
        String tag = null;
        // Needs to re-evaluate this length at each loop
        while (i < sb.length()) {
            char c = sb.charAt(i);
            if (inTag) {
                if (c == '>') {
                    // OPTION Could fail at or fix some errorneous tags here
                    // Make the best guess as to whether this tag is terminated
                    if (Comments.isMinimizedTag(tag) &&
                        htmlText.indexOf("</" + tag + ">", i) == -1)
                        sb.insert(i, "/");
                    inTag = false;
                } else {
                    // OPTION could also make sure that attribute values are
                    // surrounded by quotes.
                    tag += c;
                }
            }
            if (c == '<') {
                inTag = true;
                tag = "";
            }
            // -- is not allowed in XML, but !-- is part of an comment,
            // and --> is also part of a comment
            if (c == '-' && i > 0 && sb.charAt(i-1) == '-') {
                if (!(i > 1 && sb.charAt(i-2) == '!')) { 
                    sb.setCharAt(i, '&');
                    sb.insert(i+1, "#045;");
                    i += 5;
                }
            }
            i++;
        }
        if (inTag) {
            // Oops. Someone forgot to close their HTML tag, e.g. "<code."
            // Close it for them.
            sb.insert(i, ">");
        }
        return sb.toString();
    }
}
