package org.incava.doctorj;

import java.util.List;
import java.util.Map;
import org.incava.analysis.Report;
import org.incava.java.*;
import org.incava.log.Log;


/**
 * Analyzes Javadoc and code for a type, which is a class (concrete or abstract)
 * or an interface.
 */
public abstract class TypeDocAnalyzer extends ItemDocAnalyzer
{
    /**
     * The message for an author without a name.
     */
    public final static String MSG_AUTHOR_WITHOUT_NAME = "@author without name text";

    /**
     * The message for a version without associated text.
     */
    public final static String MSG_VERSION_WITHOUT_TEXT = "@version without text";

    /**
     * The message for a serial field without a description.
     */
    public final static String MSG_SERIAL_WITHOUT_TEXT = "@serial without field description";

    /**
     * The node to which this type applies.
     */
    private SimpleNode node;
    
    /**
     * Creates an analyzer, but does not yet run.
     */
    public TypeDocAnalyzer(Report r, SimpleNode node)
    {
        super(r, node);
        this.node = node;
    }

    /**
     * Checks the Javadoc against that expected by a type.
     */
    protected void checkJavadoc(JavadocNode javadoc)
    {
        super.checkJavadoc(javadoc);

        if (javadoc != null && isCheckable(node, CHKLVL_TAG_CONTENT)) {
            JavadocTaggedNode[] taggedComments = javadoc.getTaggedComments();
            for (int ti = 0; ti < taggedComments.length; ++ti) {
                JavadocTag tag = taggedComments[ti].getTag();
                Log.log("considering tag: " + tag);
                if (tag.text.equals(JavadocTags.AUTHOR)) {
                    checkForTagDescription(taggedComments[ti], MSG_AUTHOR_WITHOUT_NAME);
                }
                else if (tag.text.equals(JavadocTags.VERSION)) {
                    checkForTagDescription(taggedComments[ti], MSG_VERSION_WITHOUT_TEXT);
                }
                else if (tag.text.equals(JavadocTags.SERIAL)) {
                    checkForTagDescription(taggedComments[ti], MSG_SERIAL_WITHOUT_TEXT);
                }
            }
        }
    }

    /**
     * Adds a violation, for something that is not documented.
     */
    protected void addUndocumentedViolation(String desc)
    {
        // both the outer class/interface and inner class/interface are the
        // same.

        SimpleNode declaration = (SimpleNode)node.jjtGetChild(0);
        Token name = (Token)declaration.getChildren().get(1);
        Log.log("name: " + name);
        addViolation(desc, name);
    }

}
