//===-- 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/StringConvert.h"
#include "lldb/Host/XML.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();
}

llvm::StringRef 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();
}

bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value,
                                          uint64_t fail_value, int base) const {
#if defined(LIBXML2_DEFINED)
  llvm::StringRef str_value = GetAttributeValue(name, "");
#else
  llvm::StringRef str_value;
#endif
  bool success = false;
  value = StringConvert::ToUInt64(str_value.data(), fail_value, base, &success);
  return success;
}

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](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() {}

llvm::StringRef 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;
}
