//===-- XML.cpp -------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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 = nullptr;
#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))
            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)))
        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)))
        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)))
        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 == key) {
              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;
}
