// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "DFPlatform.h"
#include "DFXML.h"
#include "DFDOM.h"
#include "DFMarkupCompatibility.h"
#include "DFHTML.h"
#include "DFBuffer.h"
#include "DFString.h"
#include "DFCommon.h"
#include <assert.h>
#include <libxml/tree.h>
#include <libxml/xmlwriter.h>
#include <string.h>

const xmlChar *INDENT =
(const xmlChar *)"\n                                                                                "\
"                                                                                "\
"                                                                                "\
"                                                                                ";

static int HTML_requiresCloseTag(Tag tag)
{
    // FIXME: Check for any other such tags
    switch (tag) {
        case HTML_IMG:
        case HTML_BR:
        case HTML_META:
        case HTML_LINK:
        case HTML_HR:
        case HTML_COL:
            return 0;
        default:
            return 1;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                           DFSAXParser                                          //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

static void DFSAXSetup(xmlSAXHandler *handler);

typedef struct DFSAXParser DFSAXParser;

struct DFSAXParser {
    DFDocument *document;
    DFBuffer *warnings;
    DFBuffer *errors;
    DFBuffer *fatalErrors;
    DFMarkupCompatibility *compatibility;
    unsigned int ignoreDepth;

    DFNode *parent; // not explicitly retained
};

DFSAXParser *DFSAXParserNew(void)
{
    DFSAXParser *parser = (DFSAXParser *)xcalloc(1,sizeof(DFSAXParser));
    parser->document = DFDocumentNew();
    parser->parent = parser->document->docNode;
    parser->warnings = DFBufferNew();
    parser->errors = DFBufferNew();
    parser->fatalErrors = DFBufferNew();
    parser->compatibility = DFMarkupCompatibilityNew();
    return parser;
}

void DFSAXParserFree(DFSAXParser *parser)
{
    DFDocumentRelease(parser->document);
    DFBufferRelease(parser->warnings);
    DFBufferRelease(parser->errors);
    DFBufferRelease(parser->fatalErrors);
    DFMarkupCompatibilityFree(parser->compatibility);
    free(parser);
}

void DFSAXParserParse(DFSAXParser *parser, const void *data, size_t len)
{
    xmlSAXHandler handler;
    DFSAXSetup(&handler);
    xmlSAXUserParseMemory(&handler,parser,data,(int)len);
}

static void SAXStartElementNS(void *ctx, const xmlChar *localname,
                              const xmlChar *prefix, const xmlChar *URI,
                              int nb_namespaces, const xmlChar **namespaces,
                              int nb_attributes, int nb_defaulted, const xmlChar **attributes)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;

    if (parser->ignoreDepth > 0) {
        parser->ignoreDepth++;
        return;
    }

    for (int i = 0; i < nb_namespaces; i++) {
        const xmlChar *nsPrefix = namespaces[i*2];
        const xmlChar *nsURI = namespaces[i*2+1];
        DFNameMapFoundNamespace(parser->document->map,(const char *)nsURI,(const char *)nsPrefix);
    }

    Tag tag = DFNameMapTagForName(parser->document->map,(const char *)URI,(const char *)localname);

    if (parser->compatibility != NULL) {
        const TagDecl *tagDecl = DFNameMapNameForTag(parser->document->map,tag);
        MCAction action = DFMarkupCompatibilityLookup(parser->compatibility,tagDecl->namespaceID,tag,1);
        if (action == MCActionIgnore) {
            parser->ignoreDepth++;
            return;
        }
    }

    if (parser->compatibility != NULL) {
        DFMarkupCompatibilityPush(parser->compatibility,nb_namespaces,(const char **)namespaces,parser->document->map);
    }

    DFNode *element = DFCreateElement(parser->document,tag);
    for (int i = 0; i < nb_attributes; i++) {
        const xmlChar *attrLocalName = attributes[i*5+0];
        const xmlChar *attrURI = attributes[i*5+2];
        const xmlChar *attrValueStart = attributes[i*5+3];
        const xmlChar *attrValueEnd = attributes[i*5+4];
        unsigned long attrValueLen = (unsigned long)(attrValueEnd - attrValueStart);

        Tag attrTag = DFNameMapTagForName(parser->document->map,(const char *)attrURI,(const char *)attrLocalName);
        const TagDecl *attrTagDecl = DFNameMapNameForTag(parser->document->map,attrTag);
        char *attrValue = (char *)xmalloc(attrValueLen+1);
        memcpy(attrValue,attrValueStart,attrValueLen);
        attrValue[attrValueLen] = '\0';
        if (parser->compatibility != NULL) {
            switch (attrTag) {
                case MC_IGNORABLE:
                case MC_PROCESSCONTENT:
                case MC_MUSTUNDERSTAND:
                    DFMarkupCompatibilityProcessAttr(parser->compatibility,attrTag,attrValue,parser->document->map);
                    break;
                default: {
                    MCAction action = DFMarkupCompatibilityLookup(parser->compatibility,attrTagDecl->namespaceID,0,0);
                    if (action != MCActionIgnore)
                        DFSetAttribute(element,attrTag,attrValue);
                    break;
                }
            }
        }
        else {
            DFSetAttribute(element,attrTag,attrValue);
        }
        free(attrValue);
    }

    DFAppendChild(parser->parent,element);
    parser->parent = element;
    if (parser->document->root == NULL)
        parser->document->root = element;
}

static void SAXEndElementNS(void *ctx, const xmlChar *localname,
                            const xmlChar *prefix, const xmlChar *URI)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;

    if (parser->ignoreDepth > 0) {
        parser->ignoreDepth--;
        return;
    }

    if (parser->compatibility != NULL)
        DFMarkupCompatibilityPop(parser->compatibility);

    assert(parser->parent != NULL);
    parser->parent = parser->parent->parent;
    assert(parser->parent != NULL);
}

// SAXStartElement and SAXEndElement are used only when parsing HTML

static void SAXStartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    const NamespaceDecl *namespaceDecl = DFNameMapNamespaceForID(parser->document->map,NAMESPACE_HTML);
    Tag tag = DFNameMapTagForName(parser->document->map,namespaceDecl->namespaceURI,(const char *)fullname);
    DFNode *element = DFCreateElement(parser->document,tag);
    if (atts != NULL) {
        for (int i = 0; atts[i] != NULL; i += 2) {
            const xmlChar *name = atts[i];
            const xmlChar *value = atts[i+1];
            Tag attrTag = DFNameMapTagForName(parser->document->map,namespaceDecl->namespaceURI,(const char *)name);
            DFSetAttribute(element,attrTag,(const char *)value);
        }
    }
    DFAppendChild(parser->parent,element);
    parser->parent = element;
    if (parser->document->root == NULL)
        parser->document->root = element;
}

static void SAXEndElement(void *ctx, const xmlChar *name)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    assert(parser->parent != NULL);
    parser->parent = parser->parent->parent;
    assert(parser->parent != NULL);
}

static void SAXCharacters(void *ctx, const xmlChar *ch, int len)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    if (parser->ignoreDepth > 0)
        return;
    char *data = (char *)xmalloc(len+1);
    memcpy(data,ch,len);
    data[len] = '\0';
    DFNode *text = DFCreateTextNode(parser->document,data);
    assert(parser->parent != NULL);
    DFAppendChild(parser->parent,text);
    free(data);
}

static void SAXComment(void *ctx, const xmlChar *value)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    if (parser->ignoreDepth > 0)
        return;;
    DFNode *comment = DFCreateComment(parser->document,(const char *)value);
    assert(parser->parent != NULL);
    DFAppendChild(parser->parent,comment);
}

static void SAXCDATABlock(void *ctx, const xmlChar *value, int len)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    if (parser->ignoreDepth > 0)
        return;
    char *data = (char *)xmalloc(len+1);
    memcpy(data,value,len);
    data[len] = '\0';
    DFNode *cdata = DFCreateTextNode(parser->document,data);
    assert(parser->parent != NULL);
    DFAppendChild(parser->parent,cdata);
    free(data);
}

static void SAXProcessingInstruction(void *ctx, const xmlChar *target, const xmlChar *data)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    if (parser->ignoreDepth > 0)
        return;;
    DFNode *pi = DFCreateProcessingInstruction(parser->document,(const char *)target,(const char *)data);
    assert(parser->parent != NULL);
    DFAppendChild(parser->parent,pi);
}

static void SAXWarning(void *ctx, const char *msg, ...)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    va_list ap;
    va_start(ap,msg);
    DFBufferFormat(parser->warnings,msg,ap);
    va_end(ap);
}

static void SAXError(void *ctx, const char *msg, ...)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    va_list ap;
    va_start(ap,msg);
    DFBufferFormat(parser->errors,msg,ap);
    va_end(ap);
}

static void SAXFatalError(void *ctx, const char *msg, ...)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    va_list ap;
    va_start(ap,msg);
    DFBufferFormat(parser->fatalErrors,msg,ap);
    va_end(ap);
}

static void DFSAXSetup(xmlSAXHandler *handler)
{
    bzero(handler,sizeof(xmlSAXHandler));
    handler->characters = SAXCharacters;
    handler->processingInstruction = SAXProcessingInstruction;
    handler->comment = SAXComment;
    handler->cdataBlock = SAXCDATABlock;
    handler->warning = SAXWarning;
    handler->error = SAXError;
    handler->error = SAXFatalError;
    handler->startElementNs = SAXStartElementNS;
    handler->endElementNs = SAXEndElementNS;
    handler->startElement = SAXStartElement;
    handler->endElement = SAXEndElement;
    handler->initialized = XML_SAX2_MAGIC;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                              DFXML                                             //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

void htmlSAXParseDoc(xmlChar * cur, const char * encoding, xmlSAXHandlerPtr sax, void * userData);

typedef struct {
    xmlTextWriterPtr writer;
    DFDocument *doc;
    NamespaceID defaultNS;
    int html;
    int indent;
} Serialization;

static void writeNode(Serialization *serialization, DFNode *node, int depth);

static void findUsedNamespaces(DFDocument *doc, DFNode *node, char *used, NamespaceID count)
{
    if (node->tag < MIN_ELEMENT_TAG)
        return;;
    const TagDecl *tagDecl = DFNameMapNameForTag(doc->map,node->tag);
    assert(tagDecl != NULL);
    assert(tagDecl->namespaceID < count);
    used[tagDecl->namespaceID] = 1;

    // Attributes
    if (node->tag >= MIN_ELEMENT_TAG) {
        for (unsigned int i = 0; i < node->attrsCount; i++) {
            Tag tag = node->attrs[i].tag;
            const TagDecl *attrDecl = DFNameMapNameForTag(doc->map,tag);
            assert(attrDecl != NULL);
            if ((attrDecl->namespaceID != NAMESPACE_NULL) &&
                (attrDecl->namespaceID != NAMESPACE_XML))
                used[attrDecl->namespaceID] = 1;
        }
    }

    // Children
    for (DFNode *child = node->first; child != NULL; child = child->next)
        findUsedNamespaces(doc,child,used,count);
}

static void writeNamespaceDeclarations(Serialization *serialization, DFNode *node)
{
    NamespaceID count = DFNameMapNamespaceCount(serialization->doc->map);
    char *used = (char *)xcalloc(1,count);
    findUsedNamespaces(serialization->doc,node,used,count);
    for (NamespaceID nsId = 1; nsId < count; nsId++) { // don't write null namespace
        if (used[nsId]) {
            const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,nsId);
            const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
            const xmlChar *URI = (const xmlChar *)nsDecl->namespaceURI;
            if (nsId == serialization->defaultNS)
                xmlTextWriterWriteAttribute(serialization->writer,(const xmlChar *)"xmlns",URI);
            else
                xmlTextWriterWriteAttributeNS(serialization->writer,(const xmlChar *)"xmlns",prefix,NULL,URI);
        }
    }
    free(used);
}

static int compareAttrs(const void *a, const void *b)
{
    const DFAttribute *attrA = (const DFAttribute *)a;
    const DFAttribute *attrB = (const DFAttribute *)b;
    if (attrA->tag < attrB->tag)
        return -1;
    else if (attrA->tag > attrB->tag)
        return 1;
    else
        return 0;
}

static void writeAttributes(Serialization *serialization, DFNode *element)
{
    // Sort the keys by their tag, to ensure that we always write attributes out in the same order.
    // This is important for automated tests which rely on consistent output for a given XML tree.
    DFAttribute *attrs = (DFAttribute *)xmalloc(element->attrsCount*sizeof(DFAttribute));
    memcpy(attrs,element->attrs,element->attrsCount*sizeof(DFAttribute));
    qsort(attrs,element->attrsCount,sizeof(DFAttribute),compareAttrs);

    for (unsigned int i = 0; i < element->attrsCount; i++) {
        Tag tag = attrs[i].tag;

        const TagDecl *tagDecl = DFNameMapNameForTag(serialization->doc->map,tag);
        assert(tagDecl != NULL);
        const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,tagDecl->namespaceID);
        assert(nsDecl != NULL);

        const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
        const xmlChar *localName = (const xmlChar *)tagDecl->localName;
        const xmlChar *value = (const xmlChar *)attrs[i].value;

        if (serialization->html && (tagDecl->namespaceID == NAMESPACE_HTML))
            xmlTextWriterWriteAttribute(serialization->writer,localName,value);
        else
            xmlTextWriterWriteAttributeNS(serialization->writer,prefix,localName,NULL,value);
    }
    free(attrs);
}

static void writeElement(Serialization *serialization, DFNode *element, int depth)
{
    const TagDecl *tagDecl = DFNameMapNameForTag(serialization->doc->map,element->tag);
    assert(tagDecl != NULL);
    const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,tagDecl->namespaceID);
    assert(nsDecl != NULL);

    const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
    const xmlChar *localName = (const xmlChar *)tagDecl->localName;

    if (serialization->indent && (element->parent != element->doc->docNode))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);

    if (serialization->html || (tagDecl->namespaceID == serialization->defaultNS))
        xmlTextWriterStartElement(serialization->writer,localName);
    else
        xmlTextWriterStartElementNS(serialization->writer,prefix,localName,NULL);

    if ((element->parent == serialization->doc->docNode) && !serialization->html)
        writeNamespaceDeclarations(serialization,element);

    writeAttributes(serialization,element);

    // Check if all children are text nodes. If this is true; we should treat them as if they are a single text
    // node, and not do any indentation.
    int allChildrenText = 1;
    for (DFNode *child = element->first; child != NULL; child = child->next) {
        if (child->tag != DOM_TEXT)
            allChildrenText = 0;
    }

    if (allChildrenText) {
        int oldIndent = serialization->indent;
        serialization->indent = 0;
        for (DFNode *child = element->first; child != NULL; child = child->next)
            writeNode(serialization,child,depth+2);
        serialization->indent = oldIndent;
    }
    else {
        for (DFNode *child = element->first; child != NULL; child = child->next)
            writeNode(serialization,child,depth+2);
    }

    if (serialization->indent && (element->first != NULL) && !allChildrenText) {
        if ((element->first != element->last) ||
            (element->first->tag != DOM_TEXT))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);
    }

    if (serialization->html && (element->first == NULL) && HTML_requiresCloseTag(element->tag)) {
        xmlTextWriterWriteString(serialization->writer,(xmlChar *)"");
    }

    xmlTextWriterEndElement(serialization->writer);
}

static void writeNode(Serialization *serialization, DFNode *node, int depth)
{
    switch (node->tag) {
        case DOM_DOCUMENT: {
            if (!serialization->html)
                xmlTextWriterStartDocument(serialization->writer,"1.0","UTF-8","yes");
            if (serialization->html)
                xmlTextWriterWriteDTD(serialization->writer,(xmlChar *)"html",NULL,NULL,NULL);
//            xmlTextWriterWriteDTD(writer,
//                                  (xmlChar *)"html",
//                                  (xmlChar *)"-//W3C//DTD XHTML 1.0 Strict//EN",
//                                  (xmlChar *)"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
//                                  NULL);
            for (DFNode *child = node->first; child != NULL; child = child->next)
                writeNode(serialization,child,0);
            xmlTextWriterEndDocument(serialization->writer);
            break;
        }
        case DOM_TEXT: {
            if (serialization->indent && ((node->prev != NULL) || (node->next != NULL)))
                xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);
            if (serialization->html && (node->parent != NULL) && (node->parent->tag == HTML_STYLE)) {
                xmlTextWriterWriteRaw(serialization->writer,(const xmlChar *)node->value);
            }
            else {
                xmlTextWriterWriteString(serialization->writer,(const xmlChar *)node->value);
            }
            break;
        }
        case DOM_COMMENT: {
            xmlTextWriterWriteComment(serialization->writer,(const xmlChar *)node->value);
            break;
        }
        case DOM_CDATA: {
            xmlTextWriterWriteCDATA(serialization->writer,(const xmlChar *)node->value);
            break;
        }
        case DOM_PROCESSING_INSTRUCTION: {
            xmlTextWriterWritePI(serialization->writer,
                                 (const xmlChar *)node->target,
                                 (const xmlChar *)node->value);
            break;
        }
        default: {
            if (node->parent == serialization->doc->docNode)
                writeElement(serialization,node,0);
            else
                writeElement(serialization,node,depth);
            break;
        }
    }
}

DFDocument *DFParseXMLString(const char *str, DFError **error)
{
    DFSAXParser *parser = DFSAXParserNew();
    DFSAXParserParse(parser,str,strlen(str));
    if (parser->fatalErrors->len > 0) {
        DFErrorFormat(error,"%s",parser->fatalErrors->data);
        DFSAXParserFree(parser);
        return NULL;
    }
    else if (parser->errors->len > 0) {
        DFErrorFormat(error,"%s",parser->errors->data);
        DFSAXParserFree(parser);
        return NULL;
    }
    else if (parser->document->root == NULL) {
        DFErrorFormat(error,"No root element");
        DFSAXParserFree(parser);
        return NULL;
    }

    DFDocument *result = DFDocumentRetain(parser->document);
    DFSAXParserFree(parser);
    return result;
}

DFDocument *DFParseXMLFile(const char *filename, DFError **error)
{
    DFBuffer *buf = DFBufferReadFromFile(filename,error);
    if (buf == NULL)
        return NULL;;
    DFDocument *doc = DFParseXMLString(buf->data,error);
    DFBufferRelease(buf);
    return doc;
}

DFDocument *DFParseXMLStorage(DFStorage *storage, const char *filename, DFError **error)
{
    DFBuffer *content = DFBufferReadFromStorage(storage,filename,error);
    if (content == NULL)
        return NULL;;
    DFDocument *doc = DFParseXMLString(content->data,error);
    DFBufferRelease(content);
    return doc;
}

static int StringBufferWrite(void *context, const char *buffer, int len)
{
    DFBuffer *buf = (DFBuffer *)context;
    DFBufferAppendData(buf,buffer,len);
    return len;
}

static int StringBufferClose(void *context)
{
    return 0;
}

void DFSerializeXMLBuffer(DFDocument *doc, NamespaceID defaultNS, int indent, DFBuffer *buf)
{
    xmlOutputBufferPtr output = xmlOutputBufferCreateIO(StringBufferWrite,
                                                        StringBufferClose,
                                                        buf,
                                                        NULL);
    xmlTextWriterPtr writer = xmlNewTextWriter(output);

    int html = 0;
    for (DFNode *child = doc->docNode->first; child != NULL; child = child->next) {
        if (child->tag == HTML_HTML)
            html = 1;
    }

    Serialization serialization;
    bzero(&serialization,sizeof(serialization));
    serialization.writer = writer;
    serialization.doc = doc;
    serialization.defaultNS = defaultNS;
    serialization.html = html;
    serialization.indent = indent;
    writeNode(&serialization,doc->docNode,0);
    xmlFreeTextWriter(writer);
}

char *DFSerializeXMLString(DFDocument *doc, NamespaceID defaultNS, int indent)
{
    DFBuffer *buf = DFBufferNew();
    DFSerializeXMLBuffer(doc,defaultNS,indent,buf);
    char *result = xstrdup(buf->data);
    DFBufferRelease(buf);
    return result;
}

int DFSerializeXMLFile(DFDocument *doc, NamespaceID defaultNS, int indent, const char *filename, DFError **error)
{
    DFBuffer *buf = DFBufferNew();
    DFSerializeXMLBuffer(doc,defaultNS,indent,buf);
    int r = DFBufferWriteToFile(buf,filename,error);
    DFBufferRelease(buf);
    return r;
}

int DFSerializeXMLStorage(DFDocument *doc, NamespaceID defaultNS, int indent,
                          DFStorage *storage, const char *filename,
                          DFError **error)
{
    char *str = DFSerializeXMLString(doc,defaultNS,indent);
    DFBuffer *content = DFBufferNew();
    DFBufferAppendString(content,str);
    int r = DFBufferWriteToStorage(content,storage,filename,error);
    DFBufferRelease(content);
    free(str);
    return r;
}
