package org.freemarker.docgen;

import static org.freemarker.docgen.DocBook5Constants.AV_CONFORMANCE_DOCGEN;
import static org.freemarker.docgen.DocBook5Constants.A_CONFORMANCE;
import static org.freemarker.docgen.DocBook5Constants.A_LANGUAGE;
import static org.freemarker.docgen.DocBook5Constants.A_ROLE;
import static org.freemarker.docgen.DocBook5Constants.A_XML_ID;
import static org.freemarker.docgen.DocBook5Constants.A_XREFLABEL;
import static org.freemarker.docgen.DocBook5Constants.E_ANCHOR;
import static org.freemarker.docgen.DocBook5Constants.E_APPENDIX;
import static org.freemarker.docgen.DocBook5Constants.E_ARTICLE;
import static org.freemarker.docgen.DocBook5Constants.E_BOOK;
import static org.freemarker.docgen.DocBook5Constants.E_CHAPTER;
import static org.freemarker.docgen.DocBook5Constants.E_COL;
import static org.freemarker.docgen.DocBook5Constants.E_COLGROUP;
import static org.freemarker.docgen.DocBook5Constants.E_FOOTNOTE;
import static org.freemarker.docgen.DocBook5Constants.E_GLOSSARY;
import static org.freemarker.docgen.DocBook5Constants.E_GLOSSENTRY;
import static org.freemarker.docgen.DocBook5Constants.E_INDEX;
import static org.freemarker.docgen.DocBook5Constants.E_INDEXTERM;
import static org.freemarker.docgen.DocBook5Constants.E_INFO;
import static org.freemarker.docgen.DocBook5Constants.E_INFORMALTABLE;
import static org.freemarker.docgen.DocBook5Constants.E_ITEMIZEDLIST;
import static org.freemarker.docgen.DocBook5Constants.E_LINK;
import static org.freemarker.docgen.DocBook5Constants.E_LISTITEM;
import static org.freemarker.docgen.DocBook5Constants.E_MEDIAOBJECT;
import static org.freemarker.docgen.DocBook5Constants.E_NOTE;
import static org.freemarker.docgen.DocBook5Constants.E_OLINK;
import static org.freemarker.docgen.DocBook5Constants.E_ORDEREDLIST;
import static org.freemarker.docgen.DocBook5Constants.E_PARA;
import static org.freemarker.docgen.DocBook5Constants.E_PART;
import static org.freemarker.docgen.DocBook5Constants.E_PREFACE;
import static org.freemarker.docgen.DocBook5Constants.E_PRIMARY;
import static org.freemarker.docgen.DocBook5Constants.E_PRODUCTNAME;
import static org.freemarker.docgen.DocBook5Constants.E_PROGRAMLISTING;
import static org.freemarker.docgen.DocBook5Constants.E_QUANDAENTRY;
import static org.freemarker.docgen.DocBook5Constants.E_SECONDARY;
import static org.freemarker.docgen.DocBook5Constants.E_SECTION;
import static org.freemarker.docgen.DocBook5Constants.E_SIMPLESECT;
import static org.freemarker.docgen.DocBook5Constants.E_SUBTITLE;
import static org.freemarker.docgen.DocBook5Constants.E_TABLE;
import static org.freemarker.docgen.DocBook5Constants.E_TBODY;
import static org.freemarker.docgen.DocBook5Constants.E_TD;
import static org.freemarker.docgen.DocBook5Constants.E_TFOOT;
import static org.freemarker.docgen.DocBook5Constants.E_TH;
import static org.freemarker.docgen.DocBook5Constants.E_THEAD;
import static org.freemarker.docgen.DocBook5Constants.E_TITLE;
import static org.freemarker.docgen.DocBook5Constants.E_TITLEABBREV;
import static org.freemarker.docgen.DocBook5Constants.E_TR;
import static org.freemarker.docgen.DocBook5Constants.E_WARNING;
import static org.freemarker.docgen.DocBook5Constants.XMLNS_DOCBOOK5;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeSet;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * Adds Docgen-specific restrictions to an already existing DocBook 5 validator.
 */
class DocgenRestrictionsValidator implements ContentHandler {

    public static final int MAX_SECTION_NESTING_LEVEL = 3;

    private static final Set<String> SUPPORTED_ELEMENTS;
    static {
        Set<String> supportedElements = new TreeSet<String>();

        supportedElements.add(E_ANCHOR);
        supportedElements.add("answer");
        supportedElements.add(E_APPENDIX);
        supportedElements.add(E_ARTICLE);
        supportedElements.add(E_BOOK);
        supportedElements.add(E_CHAPTER);
        supportedElements.add("classname");
        supportedElements.add(E_COL);
        supportedElements.add(E_COLGROUP);
        supportedElements.add("emphasis");
        supportedElements.add("entry");
        supportedElements.add(E_FOOTNOTE);
        supportedElements.add(E_GLOSSARY);
        supportedElements.add("glossdef");
        supportedElements.add(E_GLOSSENTRY);
        supportedElements.add("glosssee");
        supportedElements.add("glossseealso");
        supportedElements.add("glossterm");
        supportedElements.add("imagedata");
        supportedElements.add("imageobject");
        supportedElements.add(E_INDEX);
        supportedElements.add(E_INDEXTERM);
        supportedElements.add(E_INFO);
        supportedElements.add(E_INFORMALTABLE);
        supportedElements.add(E_ITEMIZEDLIST);
        supportedElements.add(E_LINK);
        supportedElements.add(E_LISTITEM);
        supportedElements.add("literal");
        supportedElements.add(E_MEDIAOBJECT);
        supportedElements.add("methodname");
        supportedElements.add(E_NOTE);
        supportedElements.add(E_OLINK);
        supportedElements.add(E_ORDEREDLIST);
        supportedElements.add("package");
        supportedElements.add(E_PARA);
        supportedElements.add(E_PART);
        supportedElements.add("phrase");
        supportedElements.add(E_PREFACE);
        supportedElements.add(E_PRIMARY);
        supportedElements.add(E_PRODUCTNAME);
        supportedElements.add(E_PROGRAMLISTING);
        supportedElements.add(E_QUANDAENTRY);
        supportedElements.add("qandaset");
        supportedElements.add("question");
        supportedElements.add("quote");
        supportedElements.add("remark");
        supportedElements.add("replaceable");
        supportedElements.add(E_SECONDARY);
        supportedElements.add(E_SECTION);
        supportedElements.add(E_SIMPLESECT);
        supportedElements.add(E_SUBTITLE);
        supportedElements.add(E_TBODY);
        supportedElements.add(E_TD);
        supportedElements.add(E_TFOOT);
        supportedElements.add(E_TH);
        supportedElements.add(E_THEAD);
        supportedElements.add(E_TR);
        supportedElements.add(E_TITLE);
        supportedElements.add(E_TITLEABBREV);
        supportedElements.add(E_WARNING);
        supportedElements.add("xref");

        SUPPORTED_ELEMENTS = Collections.unmodifiableSet(supportedElements);
    }

    private static final Set<String> ELEMENTS_ALLOW_ID;
    static {
        // Attention! When adding entries here, be sure that the corresponding
        // element indeed generates HTML anchors (or is an output-file element).

        Set<String> elementsAllowId = new TreeSet<String>();

        elementsAllowId.add(E_PART);
        elementsAllowId.add(E_APPENDIX);
        elementsAllowId.add(E_CHAPTER);
        elementsAllowId.add(E_SECTION);
        elementsAllowId.add(E_SIMPLESECT);
        elementsAllowId.add(E_PREFACE);
        elementsAllowId.add(E_INDEX);
        elementsAllowId.add(E_GLOSSARY);

        elementsAllowId.add(E_PARA);
        elementsAllowId.add(E_MEDIAOBJECT);
        elementsAllowId.add(E_INFORMALTABLE);
        elementsAllowId.add(E_PROGRAMLISTING);
        elementsAllowId.add(E_ITEMIZEDLIST);
        elementsAllowId.add(E_ORDEREDLIST);
        elementsAllowId.add(E_LISTITEM);

        elementsAllowId.add(E_GLOSSENTRY);
        elementsAllowId.add(E_QUANDAENTRY);

        elementsAllowId.add(E_ANCHOR);

        ELEMENTS_ALLOW_ID = Collections.unmodifiableSet(elementsAllowId);
    }

    private final ContentHandler docbook5Validator;
    private final ErrorHandler errorHandler;
    private final MessageStreamActivityMonitor errorMessageMonitor;
    private final DocgenValidationOptions options;

    private Locator locator;
    private String documentElementName;
    private int sectionNestingLevel;
    private int paraNestingLevel;
    private LinkedList<Integer> paraNestingLevelsHiddenByFootnote
            = new LinkedList<Integer>();
    private LinkedList<Integer> programlistingNestingLevelsHiddenByFootnote
            = new LinkedList<Integer>();
    private LinkedList<Integer> programlistingLineLengthHiddenByFootnote
            = new LinkedList<Integer>();
    private ArrayList<Boolean> hadClosedPara
            = new ArrayList<Boolean>();
    private ArrayList<String> elemPath
            = new ArrayList<String>();
    private int programlistingNestingLevel;
    private int invisibleElementNestingLevel;
    private int programlistingLineLength;

    /**
     * @param errorMessageMonitor Used for preventing reporting a violation
     *      that was also a DocBook 5 violation.
     */
    DocgenRestrictionsValidator(
            ContentHandler docbook5Validator, ErrorHandler errorHandler,
            MessageStreamActivityMonitor errorMessageMonitor,
            DocgenValidationOptions options) {
        if (docbook5Validator == null) {
            throw new IllegalArgumentException(
                    "\"docbook5Validator\" can't be null");
        }
        this.docbook5Validator = docbook5Validator;

        if (errorHandler == null) {
            throw new IllegalArgumentException(
                    "\"errorHandler\" can't be null");
        }
        this.errorHandler = errorHandler;

        if (errorMessageMonitor == null) {
            throw new IllegalArgumentException(
                    "\"messageMonitor\" can't be null");
        }
        this.errorMessageMonitor = errorMessageMonitor;

        if (options == null) {
            throw new IllegalArgumentException("\"options\" can't be null");
        }
        this.options = options;
    }

    public void startElement(String uri, final String localName, String name,
            Attributes atts) throws SAXException {
        boolean xmlnsOK = uri.equals(XMLNS_DOCBOOK5);
        if (xmlnsOK) {
            hadClosedPara.add(false);
            elemPath.add(localName);
        }

        errorMessageMonitor.reset();
        docbook5Validator.startElement(uri, localName, name, atts);
        if (!errorMessageMonitor.hadNewErrorMessage()) {
            if (!xmlnsOK) {
                errorHandler.error(newSAXException(
                        "Unsupported element namespace: " + uri));
            } else if (!SUPPORTED_ELEMENTS.contains(localName)) {
                if (localName.equals("sect1")
                        || localName.equals("sect2")
                        || localName.equals("sect3")
                        || localName.equals("sect4")
                        || localName.equals("sect5")) {
                    errorHandler.error(newSAXException(
                            "The \"" + localName + "\" element and other such "
                            + "numbered \"sect\"-s are not allowed; "
                            + "use \"" + E_SECTION + "\"-s instead."));
                } else {
                    errorHandler.error(newSAXException(
                            "Unsupported element: " + localName));
                }
            } else {
                startSupportedDocbook5Element(localName, atts);
            }
        }
    }

    private void startSupportedDocbook5Element(
            String localName, Attributes atts) throws SAXException {
        boolean isDocumentElem;
        if (documentElementName == null) {
            documentElementName = localName;
            isDocumentElem = true;
        } else {
            isDocumentElem = false;
        }

        if (localName.equals(E_SECTION)) {
            sectionNestingLevel++;
            if (sectionNestingLevel > MAX_SECTION_NESTING_LEVEL) {
                errorHandler.error(newSAXException(
                        "\"" + localName + "\" element nesting too deep. "
                        + "The maximum supported is "
                        + MAX_SECTION_NESTING_LEVEL
                        + " levels. Hint: Use \"" + E_SIMPLESECT
                        + "\" instead."));
            }
        } else if (localName.equals(E_PARA)) {
            paraNestingLevel++;
        } else if (localName.equals(E_ITEMIZEDLIST)
                        || localName.equals(E_ORDEREDLIST)
                        || localName.equals(E_PROGRAMLISTING)
                        || localName.equals(E_MEDIAOBJECT)) {
            checkNotInAPara(localName);
            if (localName.equals(E_PROGRAMLISTING)) {
                if (options.getProgramlistingRequiresLanguage()
                        && atts.getValue("", A_LANGUAGE) == null) {
                    errorHandler.error(newSAXException(
                            "In this book, \"" + localName
                            + "\" elements must have a \"" + A_LANGUAGE
                            + "\" attribute. Hint: If the language is so "
                            + "marginal that will not ever have syntax "
                            + "highlighter anyway, use \"unknown\" as the "
                            + "attribute value."));
                }
                if (options.getProgramlistingRequiresRole()
                        && atts.getValue("", A_ROLE) == null) {
                    errorHandler.error(newSAXException("In this book, "
                            + "\"" + localName + "\" elements "
                            + "must have a \"" + A_ROLE + "\" attribute. "
                            + "Hint: If none of the avialble roles fit, "
                            + "use \"unspecified\" as the attribute value."
                            ));
                }
                checkHasPrecedingParaInListitem(localName);

                programlistingLineLength = 0;
                programlistingNestingLevel++;
            }
        } else if (localName.equals(E_INFORMALTABLE)
                || localName.equals(E_TABLE)) {
            checkNotInAPara(localName);
            checkHasPrecedingParaInListitem(localName);
        } else if (localName.equals(E_FOOTNOTE)) {
            if (!paraNestingLevelsHiddenByFootnote.isEmpty()) {
                errorHandler.error(newSAXException("\"" + localName
                        + "\" inside another \"" + localName
                        + "\" is not allowed."));
            }
            if (programlistingNestingLevel != 0) {
                errorHandler.error(newSAXException("\"" + localName
                        + "\" inside a \"" + E_PROGRAMLISTING
                        + "\" is not allowed."));
            }
            paraNestingLevelsHiddenByFootnote.add(paraNestingLevel);
            paraNestingLevel = 0;

            programlistingNestingLevelsHiddenByFootnote.add(
                    programlistingNestingLevel);
            programlistingNestingLevel = 0;
            programlistingLineLengthHiddenByFootnote.add(
                    programlistingLineLength);
            programlistingLineLength = 0;
        } else if (localName.equals(E_ANCHOR)
                || localName.equals(E_INDEXTERM)) {
            invisibleElementNestingLevel++;
        } else if (isDocumentElem) {
            String conformance = atts.getValue("", A_CONFORMANCE);
            if (conformance == null) {
                errorHandler.error(newSAXException("The \""
                        + localName + "\" element must have a \""
                        + A_CONFORMANCE + "\" attribute. Hint: "
                        + "Add the attribute with value \""
                        + AV_CONFORMANCE_DOCGEN + "\"."));
            } else if (!conformance.equals(AV_CONFORMANCE_DOCGEN)) {
                errorHandler.error(newSAXException("The value of the \""
                        + A_CONFORMANCE + "\" attribute must be \""
                        + AV_CONFORMANCE_DOCGEN + "\"."));
            }
        }

        if (atts.getIndex(A_XML_ID) != -1
                && !ELEMENTS_ALLOW_ID.contains(localName)) {
            errorHandler.error(newSAXException("The \"" + localName
                    + "\" element can't have an \"" + A_XML_ID + "\" "
                    + "attribute (" + A_XML_ID + "=\""
                    + atts.getValue("xml:id") + "\"). (Hint: "
                    + (localName.equals(E_TITLE)
                            ? "Move the " + A_XML_ID + " over into the "
                              + "element whose \"" + E_TITLE
                              + "\" the element is."
                            : "Try moving the " + A_XML_ID
                              + " higher in the element hierarchy.")
                    + ")"));
        }

        if (atts.getIndex(A_XREFLABEL) != -1
                && !ELEMENTS_ALLOW_ID.contains(localName)) {
            errorHandler.error(newSAXException("The \"" + localName
                    + "\" element can't have an \"" + A_XREFLABEL
                    + "\" attribute, because it couldn't have a \""
                    + A_XML_ID + "\" attribute either, and hence it "
                    + "couldn't be the target of a link. (Hint: "
                    + (localName.equals(E_TITLE)
                            ? "Move the \"" + A_XREFLABEL + "\" attribute "
                              + "over into the element whose \"" + E_TITLE
                              + "\" the element is."
                            : "Try moving the " + A_XREFLABEL
                              + " higher in the element hierarchy.")
                    + ")"));
        }
    }

    private void checkNotInAPara(String localName) throws SAXException {
        if (paraNestingLevel > 0) {
            errorHandler.error(newSAXException("It's not allowed to "
                    + "put a(n) \"" + localName + "\" inside a \""
                    + E_PARA + "\". Hint: Simply split the containing "
                    + "\"" + E_PARA + "\" into two parts, or move the "
                    + "element after the \"" + E_PARA + "\"."));
        }
    }

    private void checkHasPrecedingParaInListitem(String elemName)
            throws SAXException {
        if (elemPath.get(elemPath.size() - 2).equals(E_LISTITEM)
                && !hadClosedPara.get(hadClosedPara.size() - 2)) {
            // This restriction exists as otherwise there are problems
            // with rendering it under most browsers if the element is
            // implemented as a HTML table.
            errorHandler.error(newSAXException("A(n) \""
                    + elemName + "\" in a " + "\"" + E_LISTITEM
                    + "\" must be preceded by a \"" + E_PARA + "\"."));
        }
    }

    public void endElement(String uri, String localName, String name)
            throws SAXException {
        boolean xmlnsOK = uri.equals(XMLNS_DOCBOOK5);
        try {
            docbook5Validator.endElement(uri, localName, name);
            if (xmlnsOK) {
                if (localName.equals(E_SECTION)) {
                    sectionNestingLevel--;
                } else if (localName.equals(E_PARA)) {
                    paraNestingLevel--;
                    hadClosedPara.set(hadClosedPara.size() - 2, true);
                } else if (localName.equals(E_FOOTNOTE)) {
                    paraNestingLevel
                            = paraNestingLevelsHiddenByFootnote.remove();
                    programlistingNestingLevel
                            = programlistingNestingLevelsHiddenByFootnote
                                    .remove();
                    programlistingLineLength
                            = programlistingLineLengthHiddenByFootnote.remove();
                } else if (localName.equals(E_PROGRAMLISTING)) {
                    programlistingNestingLevel--;
                } else if (localName.equals(E_ANCHOR)
                        || localName.equals(E_INDEXTERM)) {
                    invisibleElementNestingLevel--;
                }
            }
        } finally {
            if (xmlnsOK) {
                elemPath.remove(elemPath.size() - 1);
                hadClosedPara.remove(hadClosedPara.size() - 1);
            }
        }
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if (invisibleElementNestingLevel == 0
                && programlistingNestingLevel > 0) {
            int end = start + length;
            for (int i = start; i < end; i++) {
                char c = ch[i];
                if (c == 0x0A || c == 0x0D) {
                    programlistingLineLength = 0;
                } else {
                    if (c == 0x09) {
                        // Assuming tab-width 8:
                        programlistingLineLength
                                = ((programlistingLineLength / 8) + 1) * 8;
                        errorHandler.error(newSAXException(
                                "Tab character is not allowed in "
                                + "programlistings. (Hint: Use spaces instead.)"
                                ));
                    } else {
                        programlistingLineLength++;
                    }
                }
                if (programlistingLineLength
                        == options.getMaximumProgramlistingWidth() + 1) {
                    errorHandler.error(newSAXException(
                            "Line length in the programlisting exceeded "
                            + options.getMaximumProgramlistingWidth()
                            + ", which was set as the maximum in the "
                            + "(Related Docgen setting: \""
                            + Transform.SETTING_VALIDATION + "\" per \""
                            + Transform
                                .SETTING_VALIDATION_MAXIMUM_PROGRAMLISTING_WIDTH
                            + "\")"));
                }
            }
        }
        docbook5Validator.characters(ch, start, length);
    }

    public void endDocument() throws SAXException {
        docbook5Validator.endDocument();
    }

    public void endPrefixMapping(String prefix) throws SAXException {
        docbook5Validator.endPrefixMapping(prefix);
    }

    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException {
        docbook5Validator.ignorableWhitespace(ch, start, length);

    }

    public void processingInstruction(String target, String data)
            throws SAXException {
        docbook5Validator.processingInstruction(target, data);
    }

    public void setDocumentLocator(Locator locator) {
        docbook5Validator.setDocumentLocator(locator);
        this.locator = locator;
    }

    public void skippedEntity(String name) throws SAXException {
        docbook5Validator.skippedEntity(name);
    }

    public void startDocument() throws SAXException {
        docbook5Validator.startDocument();
    }

    private SAXParseException newSAXException(String message) {
        return new SAXParseException(
                "Docgen-specific DocBook restriction violated: " + message,
                locator);
    }

    public void startPrefixMapping(String prefix, String uri)
            throws SAXException {
        docbook5Validator.startPrefixMapping(prefix, uri);
    }

}
