/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AAPT_XML_DOM_H
#define AAPT_XML_DOM_H

#include <memory>
#include <string>
#include <vector>

#include "androidfw/StringPiece.h"

#include "Diagnostics.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "io/Io.h"
#include "util/Util.h"
#include "xml/XmlUtil.h"

namespace aapt {
namespace xml {

class Element;
class Visitor;

// Base class for all XML nodes.
class Node {
 public:
  virtual ~Node() = default;

  Element* parent = nullptr;
  size_t line_number = 0u;
  size_t column_number = 0u;
  std::string comment;

  virtual void Accept(Visitor* visitor) = 0;

  using ElementCloneFunc = std::function<void(const Element&, Element*)>;

  // Clones the Node subtree, using the given function to decide how to clone an Element.
  virtual std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const = 0;
};

// A namespace declaration (xmlns:prefix="uri").
struct NamespaceDecl {
  std::string prefix;
  std::string uri;
  size_t line_number = 0u;
  size_t column_number = 0u;
};

struct AaptAttribute {
  explicit AaptAttribute(const ::aapt::Attribute& attr, const Maybe<ResourceId>& resid = {})
      : attribute(attr), id(resid) {
  }

  aapt::Attribute attribute;
  Maybe<ResourceId> id;
};

// An XML attribute.
struct Attribute {
  std::string namespace_uri;
  std::string name;
  std::string value;

  Maybe<AaptAttribute> compiled_attribute;
  std::unique_ptr<Item> compiled_value;
};

// An Element XML node.
class Element : public Node {
 public:
  // Ordered namespace prefix declarations.
  std::vector<NamespaceDecl> namespace_decls;

  std::string namespace_uri;
  std::string name;
  std::vector<Attribute> attributes;
  std::vector<std::unique_ptr<Node>> children;

  void AppendChild(std::unique_ptr<Node> child);
  void InsertChild(size_t index, std::unique_ptr<Node> child);

  Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name);
  const Attribute* FindAttribute(const android::StringPiece& ns,
                                 const android::StringPiece& name) const;
  Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name);
  Element* FindChildWithAttribute(const android::StringPiece& ns, const android::StringPiece& name,
                                  const android::StringPiece& attr_ns,
                                  const android::StringPiece& attr_name,
                                  const android::StringPiece& attr_value);
  std::vector<Element*> GetChildElements();

  // Due to overriding of subtypes not working with unique_ptr, define a convenience Clone method
  // that knows cloning an element returns an element.
  std::unique_ptr<Element> CloneElement(const ElementCloneFunc& el_cloner) const;

  std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override;

  void Accept(Visitor* visitor) override;
};

// A Text (CDATA) XML node. Can not have any children.
class Text : public Node {
 public:
  std::string text;

  std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override;

  void Accept(Visitor* visitor) override;
};

// An XML resource with a source, name, and XML tree.
class XmlResource {
 public:
  ResourceFile file;

  // StringPool must come before the xml::Node. Destructors are called in reverse order, and
  // the xml::Node may have StringPool references that need to be destroyed before the StringPool
  // is destroyed.
  StringPool string_pool;

  std::unique_ptr<xml::Element> root;
};

// Inflates an XML DOM from an InputStream, logging errors to the logger.
// Returns the root node on success, or nullptr on failure.
std::unique_ptr<XmlResource> Inflate(io::InputStream* in, IDiagnostics* diag, const Source& source);

// Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
// Returns the root node on success, or nullptr on failure.
std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag,
                                     const Source& source);

Element* FindRootElement(Node* node);

// Visitor whose default implementation visits the children nodes of any node.
class Visitor {
 public:
  virtual ~Visitor() = default;

  virtual void Visit(Element* el) {
    VisitChildren(el);
  }

  virtual void Visit(Text* text) {
  }

 protected:
  Visitor() = default;

  void VisitChildren(Element* el) {
    for (auto& child : el->children) {
      child->Accept(this);
    }
  }

  virtual void BeforeVisitElement(Element* el) {
  }
  virtual void AfterVisitElement(Element* el) {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(Visitor);

  friend class Element;
};

// An XML DOM visitor that will record the package name for a namespace prefix.
class PackageAwareVisitor : public Visitor, public IPackageDeclStack {
 public:
  using Visitor::Visit;

  Maybe<ExtractedPackage> TransformPackageAlias(
      const android::StringPiece& alias, const android::StringPiece& local_package) const override;

 protected:
  PackageAwareVisitor() = default;

  void BeforeVisitElement(Element* el) override;
  void AfterVisitElement(Element* el) override;

 private:
  DISALLOW_COPY_AND_ASSIGN(PackageAwareVisitor);

  struct PackageDecl {
    std::string prefix;
    ExtractedPackage package;
  };

  std::vector<std::vector<PackageDecl>> package_decls_;
};

namespace internal {

// Base class that overrides the default behaviour and does not descend into child nodes.
class NodeCastBase : public Visitor {
 public:
  void Visit(Element* el) override {
  }
  void Visit(Text* el) override {
  }

 protected:
  NodeCastBase() = default;

  void BeforeVisitElement(Element* el) override {
  }
  void AfterVisitElement(Element* el) override {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NodeCastBase);
};

template <typename T>
class NodeCastImpl : public NodeCastBase {
 public:
  using NodeCastBase::Visit;

  NodeCastImpl() = default;

  T* value = nullptr;

  void Visit(T* v) override {
    value = v;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NodeCastImpl);
};

}  // namespace internal

template <typename T>
T* NodeCast(Node* node) {
  internal::NodeCastImpl<T> visitor;
  node->Accept(&visitor);
  return visitor.value;
}

}  // namespace xml
}  // namespace aapt

#endif  // AAPT_XML_DOM_H
