// Copyright 2015 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 BUFFET_NOTIFICATION_XMPP_STREAM_PARSER_H_
#define BUFFET_NOTIFICATION_XMPP_STREAM_PARSER_H_

#include <expat.h>

#include <map>
#include <memory>
#include <stack>
#include <string>

#include <base/macros.h>

namespace buffet {

class XmlNode;

// A simple XML stream parser. As the XML data is being read from a data source
// (for example, a socket), XmppStreamParser::ParseData() should be called.
// This method parses the provided XML data chunk and if it finds complete
// XML elements, it will call internal OnOpenElement(), OnCloseElement() and
// OnCharData() member functions. These will track the element nesting level.
// When a top-level element starts, the parser will call Delegate::OnStreamStart
// method. Once this happens, every complete XML element (including its children
// if they are present) will trigger Delegate::OnStanze() callback.
// Finally, when top-level element is closed, Delegate::OnStreamEnd() is called.
// This class is specifically tailored to XMPP streams which look like this:
// B:  <stream:stream to='example.com' xmlns='jabber:client' version='1.0'>
// S:    <presence><show/></presence>
// S:    <message to='foo'><body/></message>
// S:    <iq to='bar'><query/></iq>
// S:    ...
// E:  </stream:stream>
// Here, "B:" will trigger OnStreamStart(), "S:" will result in OnStanza() and
// "E:" will result in OnStreamEnd().
class XmppStreamParser final {
 public:
  // Delegate interface that interested parties implement to receive
  // notifications of stream opening/closing and on new stanzas arriving.
  class Delegate {
   public:
    virtual void OnStreamStart(
        const std::string& node_name,
        std::map<std::string, std::string> attributes) = 0;
    virtual void OnStreamEnd(const std::string& node_name) = 0;
    virtual void OnStanza(std::unique_ptr<XmlNode> stanza) = 0;

   protected:
    virtual ~Delegate() = default;
  };

  explicit XmppStreamParser(Delegate* delegate);
  ~XmppStreamParser();

  // Parses additional XML data received from an input stream.
  void ParseData(const std::string& data);

  // Resets the parser to expect the top-level stream node again.
  void Reset();

 private:
  // Raw expat callbacks.
  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);

  // Reinterpreted callbacks from expat with some data pre-processed.
  void OnOpenElement(const std::string& node_name,
                     std::map<std::string, std::string> attributes);
  void OnCloseElement(const std::string& node_name);
  void OnCharData(const std::string& text);

  Delegate* delegate_;
  XML_Parser parser_{nullptr};
  bool started_{false};
  std::stack<std::unique_ptr<XmlNode>> node_stack_;

  DISALLOW_COPY_AND_ASSIGN(XmppStreamParser);
};

}  // namespace buffet

#endif  // BUFFET_NOTIFICATION_XMPP_STREAM_PARSER_H_

