// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

import CoreFoundation
// Input options
//  NSXMLNodeOptionsNone
//  NSXMLNodePreserveAll
//  NSXMLNodePreserveNamespaceOrder
//  NSXMLNodePreserveAttributeOrder
//  NSXMLNodePreserveEntities
//  NSXMLNodePreservePrefixes
//  NSXMLNodePreserveCDATA
//  NSXMLNodePreserveEmptyElements
//  NSXMLNodePreserveQuotes
//  NSXMLNodePreserveWhitespace
//  NSXMLNodeLoadExternalEntities
//  NSXMLNodeLoadExternalEntitiesSameOriginOnly

//  NSXMLDocumentTidyHTML
//  NSXMLDocumentTidyXML

//  NSXMLDocumentValidate

// Output options
//  NSXMLNodePrettyPrint
//  NSXMLDocumentIncludeContentTypeDeclaration

extension XMLDocument {

    /*!
        @typedef NSXMLDocumentContentKind
        @abstract Define what type of document this is.
        @constant NSXMLDocumentXMLKind The default document type
        @constant NSXMLDocumentXHTMLKind Set if NSXMLDocumentTidyHTML is set and HTML is detected
        @constant NSXMLDocumentHTMLKind Outputs empty tags without a close tag, eg <br>
        @constant NSXMLDocumentTextKind Output the string value of the document
    */
    public enum ContentKind : UInt {

        case xml
        case xhtml
        case html
        case text
    }
}

/*!
    @class NSXMLDocument
    @abstract An XML Document
	@discussion Note: if the application of a method would result in more than one element in the children array, an exception is thrown. Trying to add a document, namespace, attribute, or node with a parent also throws an exception. To add a node with a parent first detach or create a copy of it.
*/
open class XMLDocument : XMLNode {
    private var _xmlDoc: _CFXMLDocPtr {
        return _CFXMLDocPtr(_xmlNode)
    }
    
    public init() {
        NSUnimplemented()
    }
    
    /*!
        @method initWithXMLString:options:error:
        @abstract Returns a document created from either XML or HTML, if the HTMLTidy option is set. Parse errors are returned in <tt>error</tt>.
    */
    public convenience init(xmlString string: String, options: Options) throws {
        guard let data = string.data(using: .utf8) else {
            // TODO: Throw an error
            fatalError("String: '\(string)' could not be converted to NSData using UTF-8 encoding")
        }

        try self.init(data: data, options: options)
    }

    /*!
        @method initWithContentsOfURL:options:error:
        @abstract Returns a document created from the contents of an XML or HTML URL. Connection problems such as 404, parse errors are returned in <tt>error</tt>.
    */
    public convenience init(contentsOf url: URL, options: Options) throws {
        let data = try Data(contentsOf: url, options: .mappedIfSafe)

        try self.init(data: data, options: options)
    }

    /*!
        @method initWithData:options:error:
        @abstract Returns a document created from data. Parse errors are returned in <tt>error</tt>.
    */
    public init(data: Data, options: Options) throws {
        let docPtr = _CFXMLDocPtrFromDataWithOptions(data._cfObject, Int32(options.rawValue))
        super.init(ptr: _CFXMLNodePtr(docPtr))

        if options.contains(.documentValidate) {
            try validate()
        }
    }

    /*!
        @method initWithRootElement:
        @abstract Returns a document with a single child, the root element.
    */
    public init(rootElement element: XMLElement?) {
        precondition(element?.parent == nil)

        super.init(kind: .document, options: [])
        if let element = element {
            _CFXMLDocSetRootElement(_xmlDoc, element._xmlNode)
            _childNodes.insert(element)
        }
    }

    open class func replacementClass(for cls: AnyClass) -> AnyClass {
        NSUnimplemented()
    }

    /*!
        @method characterEncoding
        @abstract Sets the character encoding to an IANA type.
    */
    open var characterEncoding: String? {
        get {
            return _CFXMLDocCharacterEncoding(_xmlDoc)?._swiftObject
        }
        set {
            if let value = newValue {
                _CFXMLDocSetCharacterEncoding(_xmlDoc, value)
            } else {
                _CFXMLDocSetCharacterEncoding(_xmlDoc, nil)
            }
        }
    }

    /*!
        @method version
        @abstract Sets the XML version. Should be 1.0 or 1.1.
    */
    open var version: String? {
        get {
            return _CFXMLDocVersion(_xmlDoc)?._swiftObject
        }
        set {
            if let value = newValue {
                precondition(value == "1.0" || value == "1.1")
                _CFXMLDocSetVersion(_xmlDoc, value)
            } else {
                _CFXMLDocSetVersion(_xmlDoc, nil)
            }
        }
    }

    /*!
        @method standalone
        @abstract Set whether this document depends on an external DTD. If this option is set the standalone declaration will appear on output.
    */
    open var isStandalone: Bool {
        get {
            return _CFXMLDocStandalone(_xmlDoc)
        }
        set {
            _CFXMLDocSetStandalone(_xmlDoc, newValue)
        }
    }//primitive

    /*!
        @method documentContentKind
        @abstract The kind of document.
    */
    open var documentContentKind: ContentKind  {
        get {
            let properties = _CFXMLDocProperties(_xmlDoc)

            if properties & Int32(_kCFXMLDocTypeHTML) != 0 {
                return .html
            }

            return .xml
        }

        set {
            var properties = _CFXMLDocProperties(_xmlDoc)
            switch newValue {
            case .html:
                properties |= Int32(_kCFXMLDocTypeHTML)

            default:
                properties &= ~Int32(_kCFXMLDocTypeHTML)
            }

            _CFXMLDocSetProperties(_xmlDoc, properties)
        }
    }//primitive

    /*!
        @method MIMEType
        @abstract Set the MIME type, eg text/xml.
    */
    open var mimeType: String?

    /*!
        @method DTD
        @abstract Set the associated DTD. This DTD will be output with the document.
    */
    /*@NSCopying*/ open var dtd: XMLDTD? {
        get {
            return XMLDTD._objectNodeForNode(_CFXMLDocDTD(_xmlDoc)!)
        }
        set {
            if let currDTD = _CFXMLDocDTD(_xmlDoc) {
                if _CFXMLNodeGetPrivateData(currDTD) != nil {
                    let DTD = XMLDTD._objectNodeForNode(currDTD)
                    _CFXMLUnlinkNode(currDTD)
                    _childNodes.remove(DTD)
                } else {
                    _CFXMLFreeDTD(currDTD)
                }
            }

            if let value = newValue {
                guard let dtd = value.copy() as? XMLDTD else {
                    fatalError("Failed to copy DTD")
                }
                _CFXMLDocSetDTD(_xmlDoc, dtd._xmlDTD)
                _childNodes.insert(dtd)
            } else {
                _CFXMLDocSetDTD(_xmlDoc, nil)
            }
        }
    }//primitive

    /*!
        @method setRootElement:
        @abstract Set the root element. Removes all other children including comments and processing-instructions.
    */
    open func setRootElement(_ root: XMLElement) {
        precondition(root.parent == nil)

        for child in _childNodes {
            child.detach()
        }

        _CFXMLDocSetRootElement(_xmlDoc, root._xmlNode)
        _childNodes.insert(root)
    }

    /*!
        @method rootElement
        @abstract The root element.
    */
    open func rootElement() -> XMLElement? {
        guard let rootPtr = _CFXMLDocRootElement(_xmlDoc) else {
            return nil
        }

        return XMLNode._objectNodeForNode(rootPtr) as? XMLElement
    }

    /*!
        @method insertChild:atIndex:
        @abstract Inserts a child at a particular index.
    */
    open func insertChild(_ child: XMLNode, at index: Int) {
        _insertChild(child, atIndex: index)
    }

    /*!
        @method insertChildren:atIndex:
        @abstract Insert several children at a particular index.
    */
    open func insertChildren(_ children: [XMLNode], at index: Int) {
        _insertChildren(children, atIndex: index)
    }

    /*!
        @method removeChildAtIndex:atIndex:
        @abstract Removes a child at a particular index.
    */
    open func removeChild(at index: Int) {
        _removeChildAtIndex(index)
    }

    /*!
        @method setChildren:
        @abstract Removes all existing children and replaces them with the new children. Set children to nil to simply remove all children.
    */
    open func setChildren(_ children: [XMLNode]?) {
        _setChildren(children)
    }

    /*!
        @method addChild:
        @abstract Adds a child to the end of the existing children.
    */
    open func addChild(_ child: XMLNode) {
        _addChild(child)
    }

    /*!
        @method replaceChildAtIndex:withNode:
        @abstract Replaces a child at a particular index with another child.
    */
    open func replaceChild(at index: Int, with node: XMLNode) {
        _replaceChildAtIndex(index, withNode: node)
    }

    /*!
        @method XMLData
        @abstract Invokes XMLDataWithOptions with NSXMLNodeOptionsNone.
    */
    /*@NSCopying*/ open var xmlData: Data { return xmlData(withOptions: []) }

    /*!
        @method XMLDataWithOptions:
        @abstract The representation of this node as it would appear in an XML document, encoded based on characterEncoding.
    */
    open func xmlData(withOptions options: Options) -> Data {
        let string = xmlString(withOptions: options)
        // TODO: support encodings other than UTF-8

        return string.data(using: .utf8) ?? Data()
    }

    /*!
        @method objectByApplyingXSLT:arguments:error:
        @abstract Applies XSLT with arguments (NSString key/value pairs) to this document, returning a new document.
    */
    open func object(byApplyingXSLT xslt: Data, arguments: [String : String]?) throws -> Any {
        NSUnimplemented()
    }

    /*!
        @method objectByApplyingXSLTString:arguments:error:
        @abstract Applies XSLT as expressed by a string with arguments (NSString key/value pairs) to this document, returning a new document.
    */
    open func object(byApplyingXSLTString xslt: String, arguments: [String : String]?) throws -> Any {
        NSUnimplemented()
    }

    /*!
        @method objectByApplyingXSLTAtURL:arguments:error:
        @abstract Applies the XSLT at a URL with arguments (NSString key/value pairs) to this document, returning a new document. Error may contain a connection error from the URL.
    */
    open func objectByApplyingXSLT(at xsltURL: URL, arguments argument: [String : String]?) throws -> Any {
        NSUnimplemented()
    }

    open func validate() throws {
        var unmanagedError: Unmanaged<CFError>? = nil
        let result = _CFXMLDocValidate(_xmlDoc, &unmanagedError)
        if !result,
            let unmanagedError = unmanagedError {
            let error = unmanagedError.takeRetainedValue()
            throw error._nsObject
        }
    }

    internal override class func _objectNodeForNode(_ node: _CFXMLNodePtr) -> XMLDocument {
        precondition(_CFXMLNodeGetType(node) == _kCFXMLTypeDocument)

        if let privateData = _CFXMLNodeGetPrivateData(node) {
            return XMLDocument.unretainedReference(privateData)
        }

        return XMLDocument(ptr: node)
    }

    internal override init(ptr: _CFXMLNodePtr) {
        super.init(ptr: ptr)
    }
}
