//
// XmlNode.swift
//

import Foundation

/**
 xml node
 */
public class XmlNode {
    public var parent: XmlNode?
    public var type: XmlNodeType?
    public var children: [XmlNode] = [XmlNode]()
    public var namespace: String?
    public var name: String?
    public var value: String?
    public var text: String?
    public var attributes: [XmlAttribute] = [XmlAttribute]()

    public var description: String? {
        return name
    }

    public init(type: XmlNodeType) {
        self.type = type
    }
    
    public var elements: [XmlElement]? {
        get {
            return children.compactMap { $0.type == .element ? $0 as? XmlElement : nil }
        }
    }
    public var firstText: XmlText? {
        guard children.isEmpty == false else {
            return nil
        }
        for node in children {
            if node.type == .text {
                return node as? XmlText
            }
        }
        return nil
    }
    public var isRoot: Bool {
        get {
            return parent == nil
        }
    }

    var attributesString: String {
        guard attributes.isEmpty == false else {
            return ""
        }
        return attributes.map { $0.description }.joined(separator: " ")
    }
    
    public func hasAttribute(name: String) -> Bool {
        guard attributes.isEmpty == false else {
            return false
        }
        for attribute in attributes {
            if attribute.name == name {
                return true
            }
        }
        return false
    }

    public func getAttribute(name: String) -> XmlAttribute? {
        guard attributes.isEmpty == false else {
            return nil
        }
        for attribute in attributes {
            if attribute.name == name {
                return attribute
            }
        }
        return nil
    }

    public func getElement(name: String) -> XmlElement? {
        guard let elements = self.elements else {
            return nil
        }
        for element in elements {
            if element.name == name {
                return element
            }
        }
        return nil
    }
    
    public func appendChild(node: XmlNode) {
        node.parent = self
        children.append(node)
    }
}
