// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_
#define CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_

#include <expat.h>

#include <map>
#include <string>
#include <vector>

#include <base/macros.h>

#include "chromeos-dbus-bindings/interface.h"

namespace chromeos_dbus_bindings {

class XmlInterfaceParser {
 public:
  using XmlAttributeMap = std::map<std::string, std::string>;

  XmlInterfaceParser() = default;
  virtual ~XmlInterfaceParser() = default;

  bool ParseXmlInterfaceFile(const std::string& contents,
                             const std::vector<std::string>& ignore_interfaces);
  const std::vector<Interface>& interfaces() const { return interfaces_; }

 private:
  friend class XmlInterfaceParserTest;

  // XML tag names.
  static const char kArgumentTag[];
  static const char kInterfaceTag[];
  static const char kMethodTag[];
  static const char kNodeTag[];
  static const char kSignalTag[];
  static const char kPropertyTag[];
  static const char kAnnotationTag[];
  static const char kDocStringTag[];

  // XML attribute names.
  static const char kNameAttribute[];
  static const char kTypeAttribute[];
  static const char kDirectionAttribute[];
  static const char kAccessAttribute[];
  static const char kValueAttribute[];

  // XML argument directions.
  static const char kArgumentDirectionIn[];
  static const char kArgumentDirectionOut[];

  // XML annotations.
  static const char kTrue[];
  static const char kFalse[];

  static const char kMethodConst[];
  static const char kMethodAsync[];
  static const char kMethodIncludeDBusMessage[];

  static const char kMethodKind[];
  static const char kMethodKindSimple[];
  static const char kMethodKindNormal[];
  static const char kMethodKindAsync[];
  static const char kMethodKindRaw[];

  static const char kArgumentProtobufClass[];

  // Element callbacks on |this| called by HandleElementStart() and
  // HandleElementEnd(), respectively.
  void OnOpenElement(const std::string& element_name,
                     const XmlAttributeMap& attributes);
  void OnCloseElement(const std::string& element_name);
  void OnCharData(const std::string& content);

  // Methods for appending individual argument elements to the parser.
  void AddMethodArgument(const XmlAttributeMap& attributes);
  void AddSignalArgument(const XmlAttributeMap& attributes);

  // Finds the |element_key| element in |attributes|.  Returns true and sets
  // |element_value| on success.  Returns false otherwise.
  static bool GetElementAttribute(const XmlAttributeMap& attributes,
                                  const std::vector<std::string>& element_path,
                                  const std::string& element_key,
                                  std::string* element_value);

  // Asserts that a non-empty |element_key| attribute appears in |attributes|.
  // Returns the name on success, triggers a CHECK() otherwise.
  static std::string GetValidatedElementAttribute(
      const XmlAttributeMap& attributes,
      const std::vector<std::string>& element_path,
      const std::string& element_key);

  // Calls GetValidatedElementAttribute() for the "name" property.
  static std::string GetValidatedElementName(
      const XmlAttributeMap& attributes,
      const std::vector<std::string>& element_path);

  // Method for extracting signal/method tag attributes to a struct.
  static Interface::Argument ParseArgument(
      const XmlAttributeMap& attributes,
      const std::vector<std::string>& element_path);

  // Method for extracting property tag attributes to a struct.
  static Interface::Property ParseProperty(
      const XmlAttributeMap& attributes,
      const std::vector<std::string>& element_path);

  // Expat element callback functions.
  static void HandleElementStart(void* user_data,
                                 const XML_Char* element,
                                 const XML_Char** attr);
  static void HandleElementEnd(void* user_data, const XML_Char* element);
  static void HandleCharData(void* user_data, const char *content, int length);

  // The output of the parse.
  std::vector<Interface> interfaces_;

  // A stack of <node> names used to track the object paths for interfaces.
  std::vector<std::string> node_names_;

  // Tracks where in the element traversal our parse has taken us.
  std::vector<std::string> element_path_;

  // Tracks the last argument that we've seen.
  Interface::Argument* last_arg_;

  DISALLOW_COPY_AND_ASSIGN(XmlInterfaceParser);
};

}  // namespace chromeos_dbus_bindings

#endif  // CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_
