/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFXMLTree.c
	Copyright 1999-2002, Apple, Inc. All rights reserved.
	Responsibility: Chris Parker
*/

#include "CFInternal.h"
#include <CoreFoundation/CFXMLParser.h>

/*************/
/* CFXMLTree */
/*************/

/* Creates a childless node from desc */
CFXMLTreeRef CFXMLTreeCreateWithNode(CFAllocatorRef allocator, CFXMLNodeRef node) {
    CFTreeContext treeCtxt;
    treeCtxt.version = 0;
    treeCtxt.info = (void *)node;
    treeCtxt.retain = CFRetain;
    treeCtxt.release = CFRelease;
    treeCtxt.copyDescription = CFCopyDescription;
    return CFTreeCreate(allocator, &treeCtxt);
}

CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlNode) {
    CFTreeContext treeContext;
    treeContext.version = 0;
    CFTreeGetContext(xmlNode, &treeContext);
    return (CFXMLNodeRef)treeContext.info;
}

// We will probably ultimately want to export this under some public API name
__private_extern__ Boolean CFXMLTreeEqual(CFXMLTreeRef xmlTree1, CFXMLTreeRef xmlTree2) {
    CFXMLNodeRef node1, node2;
    CFXMLTreeRef child1, child2;
    if (CFTreeGetChildCount(xmlTree1) != CFTreeGetChildCount(xmlTree2)) return false;
    node1 = CFXMLTreeGetNode(xmlTree1);
    node2 = CFXMLTreeGetNode(xmlTree2);
    if (!CFEqual(node1, node2)) return false;
    for (child1 = CFTreeGetFirstChild(xmlTree1), child2 = CFTreeGetFirstChild(xmlTree2); child1 && child2; child1 = CFTreeGetNextSibling(child1), child2 = CFTreeGetNextSibling(child2)) {
        if (!CFXMLTreeEqual(child1, child2)) return false;
    }
    return true;
}

static void _CFAppendXML(CFMutableStringRef str, CFXMLTreeRef tree);
static void _CFAppendXMLProlog(CFMutableStringRef str, const CFXMLTreeRef node);
static void _CFAppendXMLEpilog(CFMutableStringRef str, const CFXMLTreeRef node);

CFDataRef CFXMLTreeCreateXMLData(CFAllocatorRef allocator, CFXMLTreeRef xmlTree) {
    CFMutableStringRef xmlStr; 
    CFDataRef result;
    CFStringEncoding encoding;

    __CFGenericValidateType(xmlTree, CFTreeGetTypeID());
    
    xmlStr = CFStringCreateMutable(allocator, 0);
    _CFAppendXML(xmlStr, xmlTree);
    if (CFXMLNodeGetTypeCode(CFXMLTreeGetNode(xmlTree)) == kCFXMLNodeTypeDocument) {
        const CFXMLDocumentInfo *docData = (CFXMLDocumentInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(xmlTree));
        encoding = docData ? docData->encoding : kCFStringEncodingUTF8;
    } else {
        encoding = kCFStringEncodingUTF8;
    }
    result = CFStringCreateExternalRepresentation(allocator, xmlStr, encoding, 0);
    CFRelease(xmlStr);
    return result;
}

static void _CFAppendXML(CFMutableStringRef str, CFXMLTreeRef tree) {
    CFXMLTreeRef child;
    _CFAppendXMLProlog(str, tree);
    for (child = CFTreeGetFirstChild(tree); child; child = CFTreeGetNextSibling(child)) {
        _CFAppendXML(str, child);
    }
    _CFAppendXMLEpilog(str, tree);
}

__private_extern__ void appendQuotedString(CFMutableStringRef str, CFStringRef strToQuote) {
    char quoteChar = CFStringFindWithOptions(strToQuote, CFSTR("\""), CFRangeMake(0, CFStringGetLength(strToQuote)), 0, NULL) ? '\'' : '\"';
    CFStringAppendFormat(str, NULL, CFSTR("%c%@%c"), quoteChar, strToQuote, quoteChar);
}

static void appendExternalID(CFMutableStringRef str, CFXMLExternalID *extID) {
    if (extID->publicID) {
        CFStringAppendCString(str, " PUBLIC ", kCFStringEncodingASCII);
        appendQuotedString(str, extID->publicID);
        if (extID->systemID) {
            // Technically, for externalIDs, systemID must not be NULL.  However, by testing for a NULL systemID, we can use this to emit publicIDs, too.  REW, 2/15/2000
            CFStringAppendCString(str, " ", kCFStringEncodingASCII);
            appendQuotedString(str, CFURLGetString(extID->systemID));
        }
    } else if (extID->systemID) {
        CFStringAppendCString(str, " SYSTEM ", kCFStringEncodingASCII);
        appendQuotedString(str, CFURLGetString(extID->systemID));
    } else {
        // Should never get here
    }
}

static void appendElementProlog(CFMutableStringRef str, CFXMLTreeRef tree) {
    const CFXMLElementInfo *data = (CFXMLElementInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree));
    CFStringAppendFormat(str, NULL, CFSTR("<%@"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
    if (data->attributeOrder) {
        CFIndex i, c = CFArrayGetCount(data->attributeOrder);
        for (i = 0; i < c; i ++) {
            CFStringRef attr = (CFStringRef)CFArrayGetValueAtIndex(data->attributeOrder, i);
            CFStringRef value = (CFStringRef)CFDictionaryGetValue(data->attributes, attr);
            CFStringAppendFormat(str, NULL, CFSTR(" %@="), attr);
            appendQuotedString(str, value);
        }
    }
    if (data->isEmpty) {
        CFStringAppendCString(str, "/>", kCFStringEncodingASCII);
    } else {
        CFStringAppendCString(str, ">", kCFStringEncodingASCII);
    }
}

/* Although named "prolog", for leafs of the tree, this is the only XML generation function called.  This is why Comments, Processing Instructions, etc. generate their XML during this function.  REW, 2/11/2000 */
static void _CFAppendXMLProlog(CFMutableStringRef str, const CFXMLTreeRef tree) {
    switch (CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree))) {
        case kCFXMLNodeTypeDocument:
            break;
        case kCFXMLNodeTypeElement:
            appendElementProlog(str, tree);
            break;
        case kCFXMLNodeTypeAttribute:
            // Should never be encountered
            break;
        case kCFXMLNodeTypeProcessingInstruction: {
            CFXMLProcessingInstructionInfo *data = (CFXMLProcessingInstructionInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree));
            if (data->dataString) {
                CFStringAppendFormat(str, NULL, CFSTR("<?%@ %@?>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)), data->dataString);
            } else {
                CFStringAppendFormat(str, NULL, CFSTR("<?%@?>"));
            }
            break;
        }
        case kCFXMLNodeTypeComment:
            CFStringAppendFormat(str, NULL, CFSTR("<!--%@-->"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            break;
        case kCFXMLNodeTypeText:
            CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            break;
        case kCFXMLNodeTypeCDATASection:
            CFStringAppendFormat(str, NULL, CFSTR("<![CDATA[%@]]>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            break;
        case kCFXMLNodeTypeDocumentFragment:
            break;
        case kCFXMLNodeTypeEntity: {
            CFXMLEntityInfo *data = (CFXMLEntityInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree));
            CFStringAppendCString(str, "<!ENTITY ", kCFStringEncodingASCII);
            if (data->entityType == kCFXMLEntityTypeParameter) {
                CFStringAppend(str, CFSTR("% "));
            }
            CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            CFStringAppend(str, CFSTR(" "));
            if (data->replacementText) {
                appendQuotedString(str, data->replacementText);
                CFStringAppendCString(str, ">", kCFStringEncodingASCII);
            } else {
                appendExternalID(str, &(data->entityID));
                if (data->notationName) {
                    CFStringAppendFormat(str, NULL, CFSTR(" NDATA %@"), data->notationName);
                }
                CFStringAppendCString(str, ">", kCFStringEncodingASCII);
            }
                break;
        }
        case kCFXMLNodeTypeEntityReference:
        {
            CFXMLEntityTypeCode entityType = ((CFXMLEntityReferenceInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->entityType;
            if (entityType == kCFXMLEntityTypeParameter) {
                CFStringAppendFormat(str, NULL, CFSTR("%%%@;"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            } else {
                CFStringAppendFormat(str, NULL, CFSTR("&%@;"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            }
            break;
        }
        case kCFXMLNodeTypeDocumentType:
            CFStringAppendCString(str, "<!DOCTYPE ", kCFStringEncodingASCII);
            CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            if (CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree))) {
                CFXMLExternalID *extID = &((CFXMLDocumentTypeInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->externalID;
                appendExternalID(str, extID);
            }
                CFStringAppendCString(str, " [", kCFStringEncodingASCII);
            break;
        case kCFXMLNodeTypeWhitespace:
            CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            break;
        case kCFXMLNodeTypeNotation: {
            CFXMLNotationInfo *data = (CFXMLNotationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree));
            CFStringAppendFormat(str, NULL, CFSTR("<!NOTATION %@ "), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            appendExternalID(str, &(data->externalID));
                CFStringAppendCString(str, ">", kCFStringEncodingASCII);
            break;
        }
        case kCFXMLNodeTypeElementTypeDeclaration:
            CFStringAppendFormat(str, NULL, CFSTR("<!ELEMENT %@ %@>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)), ((CFXMLElementTypeDeclarationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->contentDescription);
            break;
        case kCFXMLNodeTypeAttributeListDeclaration: {
            CFXMLAttributeListDeclarationInfo *attListData = (CFXMLAttributeListDeclarationInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree));
            CFIndex idx;
            CFStringAppendCString(str, "<!ATTLIST ", kCFStringEncodingASCII);
            CFStringAppend(str, CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
            for (idx = 0; idx < attListData->numberOfAttributes; idx ++) {
                CFXMLAttributeDeclarationInfo *attr = &(attListData->attributes[idx]);
                CFStringAppendFormat(str, NULL, CFSTR("\n\t%@ %@ %@"), attr->attributeName, attr->typeString, attr->defaultString);
            }
            CFStringAppendCString(str, ">", kCFStringEncodingASCII);
            break;
        }
        default:
            CFAssert1(false, __kCFLogAssertion, "Encountered unexpected XMLDataTypeID %d", CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree)));
    }
}

static void _CFAppendXMLEpilog(CFMutableStringRef str, const CFXMLTreeRef tree) {
    CFXMLNodeTypeCode typeID = CFXMLNodeGetTypeCode(CFXMLTreeGetNode(tree));
    if (typeID == kCFXMLNodeTypeElement) {
        if (((CFXMLElementInfo *)CFXMLNodeGetInfoPtr(CFXMLTreeGetNode(tree)))->isEmpty) return;
        CFStringAppendFormat(str, NULL, CFSTR("</%@>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
    } else if (typeID == kCFXMLNodeTypeDocumentType) {
        CFIndex len = CFStringGetLength(str);
        if (CFStringHasSuffix(str, CFSTR(" ["))) {
            // There were no in-line DTD elements
            CFStringDelete(str, CFRangeMake(len-2, 2));
        } else {
            CFStringAppendCString(str, "]", kCFStringEncodingASCII);
        }
        CFStringAppendCString(str, ">", kCFStringEncodingASCII);
    }
}


