//===-- XML.cpp -------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <stdlib.h>     /* atof */

#include "lldb/Host/XML.h"
#include "lldb/Host/StringConvert.h"

using namespace lldb;
using namespace lldb_private;


#pragma mark -- XMLDocument

XMLDocument::XMLDocument () :
    m_document (nullptr)
{
}

XMLDocument::~XMLDocument ()
{
    Clear();
}

void
XMLDocument::Clear()
{
#if defined( LIBXML2_DEFINED )
    if (m_document)
    {
        xmlDocPtr doc = m_document;
        m_document = nullptr;
        xmlFreeDoc(doc);
    }
#endif
}

bool
XMLDocument::IsValid() const
{
    return m_document != nullptr;
}

void
XMLDocument::ErrorCallback (void *ctx, const char *format, ...)
{
    XMLDocument *document = (XMLDocument *)ctx;
    va_list args;
    va_start (args, format);
    document->m_errors.PrintfVarArg(format, args);
    document->m_errors.EOL();
    va_end (args);
}

bool
XMLDocument::ParseFile (const char *path)
{
#if defined( LIBXML2_DEFINED )
    Clear();
    xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback );
    m_document = xmlParseFile(path);
    xmlSetGenericErrorFunc(nullptr, nullptr);
#endif
    return IsValid();
}

bool
XMLDocument::ParseMemory (const char *xml, size_t xml_length, const char *url)
{
#if defined( LIBXML2_DEFINED )
    Clear();
    xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback );
    m_document = xmlReadMemory(xml, (int)xml_length, url, nullptr, 0);
    xmlSetGenericErrorFunc(nullptr, nullptr);
#endif
    return IsValid();
    
}

XMLNode
XMLDocument::GetRootElement(const char *required_name)
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        XMLNode root_node(xmlDocGetRootElement(m_document));
        if (required_name)
        {
            llvm::StringRef actual_name = root_node.GetName();
            if (actual_name == required_name)
                return root_node;
        }
        else
        {
            return root_node;
        }
    }
#endif
    return XMLNode();
}

const std::string &
XMLDocument::GetErrors() const
{
    return m_errors.GetString();
}

bool
XMLDocument::XMLEnabled ()
{
#if defined( LIBXML2_DEFINED )
    return true;
#else
    return false;
#endif
}

#pragma mark -- XMLNode

XMLNode::XMLNode() :
    m_node(nullptr)
{
}

XMLNode::XMLNode(XMLNodeImpl node) :
    m_node(node)
{
}

XMLNode::~XMLNode()
{
    
}

void
XMLNode::Clear()
{
    m_node = nullptr;
}

XMLNode
XMLNode::GetParent() const
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
        return XMLNode(m_node->parent);
    else
        return XMLNode();
#else
    return XMLNode();
#endif

}

XMLNode
XMLNode::GetSibling() const
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
        return XMLNode(m_node->next);
    else
        return XMLNode();
#else
    return XMLNode();
#endif

}

XMLNode
XMLNode::GetChild () const
{
#if defined( LIBXML2_DEFINED )

    if (IsValid())
        return XMLNode(m_node->children);
    else
        return XMLNode();
#else
    return XMLNode();
#endif

}

llvm::StringRef
XMLNode::GetAttributeValue(const char *name, const char *fail_value) const
{
    const char *attr_value = NULL;
#if defined( LIBXML2_DEFINED )

    if (IsValid())
        attr_value = (const char *)xmlGetProp(m_node, (const xmlChar *)name);
    else
        attr_value = fail_value;
#else
    attr_value = fail_value;
#endif
    if (attr_value)
        return llvm::StringRef(attr_value);
    else
        return llvm::StringRef();
}




void
XMLNode::ForEachChildNode (NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
        GetChild().ForEachSiblingNode(callback);
#endif
}

void
XMLNode::ForEachChildElement (NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )
    XMLNode child = GetChild();
    if (child)
        child.ForEachSiblingElement(callback);
#endif
}

void
XMLNode::ForEachChildElementWithName (const char *name, NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )
    XMLNode child = GetChild();
    if (child)
        child.ForEachSiblingElementWithName(name, callback);
#endif
}

void
XMLNode::ForEachAttribute (AttributeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )

    if (IsValid())
    {
        for (xmlAttrPtr attr = m_node->properties; attr != nullptr; attr=attr->next)
        {
            // check if name matches
            if (attr->name)
            {
                // check child is a text node
                xmlNodePtr child = attr->children;
                if (child->type == XML_TEXT_NODE)
                {
                    llvm::StringRef attr_value;
                    if (child->content)
                        attr_value = llvm::StringRef((const char *)child->content);
                    if (callback(llvm::StringRef((const char *)attr->name), attr_value) == false)
                        return;
                }
            }
        }
    }
#endif
}


void
XMLNode::ForEachSiblingNode (NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )

    if (IsValid())
    {
        // iterate through all siblings
        for (xmlNodePtr node = m_node; node; node=node->next)
        {
            if (callback(XMLNode(node)) == false)
                return;
        }
    }
#endif
}

void
XMLNode::ForEachSiblingElement (NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )
    
    if (IsValid())
    {
        // iterate through all siblings
        for (xmlNodePtr node = m_node; node; node=node->next)
        {
            // we are looking for element nodes only
            if (node->type != XML_ELEMENT_NODE)
                continue;
            
            if (callback(XMLNode(node)) == false)
                return;
        }
    }
#endif
}

void
XMLNode::ForEachSiblingElementWithName (const char *name, NodeCallback const &callback) const
{
#if defined( LIBXML2_DEFINED )
    
    if (IsValid())
    {
        // iterate through all siblings
        for (xmlNodePtr node = m_node; node; node=node->next)
        {
            // we are looking for element nodes only
            if (node->type != XML_ELEMENT_NODE)
                continue;
            
            // If name is nullptr, we take all nodes of type "t", else
            // just the ones whose name matches
            if (name)
            {
                if (strcmp((const char *)node->name, name) != 0)
                    continue; // Name mismatch, ignore this one
            }
            else
            {
                if (node->name)
                    continue; // nullptr name specified and this element has a name, ignore this one
            }
            
            if (callback(XMLNode(node)) == false)
                return;
        }
    }
#endif
}

llvm::StringRef
XMLNode::GetName() const
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        if (m_node->name)
            return llvm::StringRef((const char *)m_node->name);
    }
#endif
    return llvm::StringRef();
}

bool
XMLNode::GetElementText (std::string &text) const
{
    text.clear();
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        bool success = false;
        if (m_node->type == XML_ELEMENT_NODE)
        {
            // check child is a text node
            for (xmlNodePtr node = m_node->children;
                 node != nullptr;
                 node = node->next)
            {
                if (node->type == XML_TEXT_NODE)
                {
                    text.append((const char *)node->content);
                    success = true;
                }
            }
        }
        return success;
    }
#endif
    return false;
}


bool
XMLNode::GetElementTextAsUnsigned (uint64_t &value, uint64_t fail_value, int base) const
{
    bool success = false;
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        std::string text;
        if (GetElementText(text))
            value = StringConvert::ToUInt64(text.c_str(), fail_value, base, &success);
    }
#endif
    if (!success)
        value = fail_value;
    return success;
}

bool
XMLNode::GetElementTextAsFloat (double &value, double fail_value) const
{
    bool success = false;
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        std::string text;
        if (GetElementText(text))
        {
            value = atof(text.c_str());
            success = true;
        }
    }
#endif
    if (!success)
        value = fail_value;
    return success;
}



bool
XMLNode::NameIs (const char *name) const
{
#if defined( LIBXML2_DEFINED )

    if (IsValid())
    {
        // In case we are looking for a nullptr name or an exact pointer match
        if (m_node->name == (const xmlChar *)name)
            return true;
        if (m_node->name)
            return strcmp((const char *)m_node->name, name) == 0;
    }
#endif
    return false;
}

XMLNode
XMLNode::FindFirstChildElementWithName (const char *name) const
{
    XMLNode result_node;

#if defined( LIBXML2_DEFINED )
    ForEachChildElementWithName(name, [&result_node, name](const XMLNode& node) -> bool {
        result_node = node;
        // Stop iterating, we found the node we wanted
        return false;
    });
#endif

    return result_node;
}

bool
XMLNode::IsValid() const
{
    return m_node != nullptr;
}

bool
XMLNode::IsElement () const
{
#if defined( LIBXML2_DEFINED )
    if (IsValid())
        return m_node->type == XML_ELEMENT_NODE;
#endif
    return false;
}


XMLNode
XMLNode::GetElementForPath (const NamePath &path)
{
#if defined( LIBXML2_DEFINED )

    if (IsValid())
    {
        if (path.empty())
            return *this;
        else
        {
            XMLNode node = FindFirstChildElementWithName(path[0].c_str());
            const size_t n = path.size();
            for (size_t i=1; node && i<n; ++i)
                node = node.FindFirstChildElementWithName(path[i].c_str());
            return node;
        }
    }
#endif

    return XMLNode();
}


#pragma mark -- ApplePropertyList

ApplePropertyList::ApplePropertyList() :
    m_xml_doc(),
    m_dict_node()
{
    
}

ApplePropertyList::ApplePropertyList (const char *path) :
    m_xml_doc(),
    m_dict_node()
{
    ParseFile(path);
}

ApplePropertyList::~ApplePropertyList()
{
}

const std::string &
ApplePropertyList::GetErrors() const
{
    return m_xml_doc.GetErrors();
}


bool
ApplePropertyList::ParseFile (const char *path)
{
    if (m_xml_doc.ParseFile(path))
    {
        XMLNode plist = m_xml_doc.GetRootElement("plist");
        if (plist)
        {
            plist.ForEachChildElementWithName("dict", [this](const XMLNode &dict) -> bool {
                this->m_dict_node = dict;
                return false; // Stop iterating
            });
            return (bool)m_dict_node;
        }
    }
    return false;
}

bool
ApplePropertyList::IsValid() const
{
    return (bool)m_dict_node;
}

bool
ApplePropertyList::GetValueAsString (const char *key, std::string &value) const
{
    XMLNode value_node = GetValueNode (key);
    if (value_node)
        return ApplePropertyList::ExtractStringFromValueNode(value_node, value);
    return false;
}

XMLNode
ApplePropertyList::GetValueNode (const char *key) const
{
    XMLNode value_node;
#if defined( LIBXML2_DEFINED )
    
    if (IsValid())
    {
        m_dict_node.ForEachChildElementWithName("key", [key, &value_node](const XMLNode &key_node) -> bool {
            std::string key_name;
            if (key_node.GetElementText(key_name))
            {
                if (key_name.compare(key) == 0)
                {
                    value_node = key_node.GetSibling();
                    while (value_node && !value_node.IsElement())
                        value_node = value_node.GetSibling();
                    return false; // Stop iterating
                }
            }
            return true; // Keep iterating
        });
    }
#endif
    return value_node;
}

bool
ApplePropertyList::ExtractStringFromValueNode (const XMLNode &node, std::string &value)
{
    value.clear();
#if defined( LIBXML2_DEFINED )
    if (node.IsValid())
    {
        llvm::StringRef element_name = node.GetName();
        if (element_name == "true" || element_name == "false")
        {
            // The text value _is_ the element name itself...
            value = element_name.str();
            return true;
        }
        else if (element_name == "dict" || element_name == "array")
            return false; // dictionaries and arrays have no text value, so we fail
        else
            return node.GetElementText(value);
    }
#endif
    return false;
}

#if defined( LIBXML2_DEFINED )

namespace {

    StructuredData::ObjectSP
    CreatePlistValue (XMLNode node)
    {
        llvm::StringRef element_name = node.GetName();
        if (element_name == "array")
        {
            std::shared_ptr<StructuredData::Array> array_sp(new StructuredData::Array());
            node.ForEachChildElement([&array_sp](const XMLNode &node) -> bool {
                array_sp->AddItem(CreatePlistValue(node));
                return true; // Keep iterating through all child elements of the array
            });
            return array_sp;
        }
        else if (element_name == "dict")
        {
            XMLNode key_node;
            std::shared_ptr<StructuredData::Dictionary> dict_sp(new StructuredData::Dictionary());
            node.ForEachChildElement([&key_node, &dict_sp](const XMLNode &node) -> bool {
                if (node.NameIs("key"))
                {
                    // This is a "key" element node
                    key_node = node;
                }
                else
                {
                    // This is a value node
                    if (key_node)
                    {
                        std::string key_name;
                        key_node.GetElementText(key_name);
                        dict_sp->AddItem(key_name, CreatePlistValue(node));
                        key_node.Clear();
                    }
                }
                return true; // Keep iterating through all child elements of the dictionary
            });
            return dict_sp;
        }
        else if (element_name == "real")
        {
            double value = 0.0;
            node.GetElementTextAsFloat(value);
            return StructuredData::ObjectSP(new StructuredData::Float(value));
        }
        else if (element_name == "integer")
        {
            uint64_t value = 0;
            node.GetElementTextAsUnsigned(value, 0, 0);
            return StructuredData::ObjectSP(new StructuredData::Integer(value));
        }
        else if ((element_name == "string") || (element_name == "data") || (element_name == "date"))
        {
            std::string text;
            node.GetElementText(text);
            return StructuredData::ObjectSP(new StructuredData::String(std::move(text)));
        }
        else if (element_name == "true")
        {
            return StructuredData::ObjectSP(new StructuredData::Boolean(true));
        }
        else if (element_name == "false")
        {
            return StructuredData::ObjectSP(new StructuredData::Boolean(false));
        }
        return StructuredData::ObjectSP(new StructuredData::Null());
    }
}
#endif

StructuredData::ObjectSP
ApplePropertyList::GetStructuredData()
{
    StructuredData::ObjectSP root_sp;
#if defined( LIBXML2_DEFINED )
    if (IsValid())
    {
        return CreatePlistValue(m_dict_node);
    }
#endif
    return root_sp;
}
