/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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 COBALT_DOM_PARSER_LIBXML_PARSER_WRAPPER_H_
#define COBALT_DOM_PARSER_LIBXML_PARSER_WRAPPER_H_

#include <stack>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_piece.h"
#include "cobalt/base/source_location.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/node.h"
#include "cobalt/loader/decoder.h"

namespace cobalt {
namespace dom_parser {

typedef unsigned char xmlChar;

/////////////////////////////////////////////////////////////////////////////
// Libxml SAX Handlers
/////////////////////////////////////////////////////////////////////////////

// These handlers are shared between HTML parser and XML parser.

void StartDocument(void* context);
void EndDocument(void* context);
void StartElement(void* context, const xmlChar* name,
                  const xmlChar** attribute_pairs);
void EndElement(void* context, const xmlChar* name);
void Characters(void* context, const xmlChar* ch, int len);
void Comment(void* context, const xmlChar* value);
void ParserWarning(void* context, const char* message, ...);
void ParserError(void* context, const char* message, ...);
void ParserFatal(void* context, const char* message, ...);
void CDATABlock(void* context, const xmlChar* value, int len);

//////////////////////////////////////////////////////////////////
// LibxmlParserWrapper
//////////////////////////////////////////////////////////////////

class LibxmlParserWrapper {
 public:
  enum IssueSeverity {
    kNoIssue,
    kWarning,  // A simple warning
    kError,    // A recoverable error
    kFatal,    // A fatal error
    kIssueSeverityCount,
  };

  struct ParserAttribute {
    ParserAttribute() {}
    ParserAttribute(const base::StringPiece& new_name,
                    const base::StringPiece& new_value)
        : name(new_name), value(new_value) {}

    base::StringPiece name;
    base::StringPiece value;
  };
  typedef std::vector<ParserAttribute> ParserAttributeVector;

  LibxmlParserWrapper(
      const scoped_refptr<dom::Document>& document,
      const scoped_refptr<dom::Node>& parent_node,
      const scoped_refptr<dom::Node>& reference_node,
      const int dom_max_element_depth,
      const base::SourceLocation& first_chunk_location,
      const base::Callback<void(const std::string&)>& error_callback)
      : document_(document),
        parent_node_(parent_node),
        reference_node_(reference_node),
        dom_max_element_depth_(dom_max_element_depth),
        first_chunk_location_(first_chunk_location),
        error_callback_(error_callback),
        depth_limit_exceeded_(false),
        max_severity_(kNoIssue),
        total_input_size_(0) {}
  virtual ~LibxmlParserWrapper() {}

  // These functions are for Libxml interface, calls are forwarded here by
  // the SAX handlers.
  virtual void OnStartDocument();
  virtual void OnEndDocument();
  virtual void OnStartElement(const std::string& name,
                              const ParserAttributeVector& attributes);
  virtual void OnEndElement(const std::string& name);
  virtual void OnCharacters(const std::string& value);
  virtual void OnComment(const std::string& comment);
  virtual void OnParsingIssue(IssueSeverity severity,
                              const std::string& message);
  virtual void OnCDATABlock(const std::string& value);

  // These interfaces are for the decoder that uses the wrapper. The input data
  // should be UTF8, and will be ignored if not.
  virtual void DecodeChunk(const char* data, size_t size) = 0;
  virtual void Finish() = 0;

 protected:
  // Returns the source location from libxml context.
  virtual base::SourceLocation GetSourceLocation() = 0;

  // Returns true when the input is a full document, false when it's a fragment.
  bool IsFullDocument() { return document_ == parent_node_; }

  // Preprocesses the input chunk and updates the max error severity level.
  // Sets current chunk if successful.
  void PreprocessChunk(const char* data, size_t size,
                       std::string* current_chunk);

  const scoped_refptr<dom::Document>& document() { return document_; }
  const base::SourceLocation& first_chunk_location() {
    return first_chunk_location_;
  }
  const base::Callback<void(const std::string&)>& error_callback() {
    return error_callback_;
  }

  const std::stack<scoped_refptr<dom::Node> >& node_stack() {
    return node_stack_;
  }

  IssueSeverity max_severity() const { return max_severity_; }

 private:
  // Maximum total input size, as specified in Libxml's value
  // XML_MAX_TEXT_LENGTH in parserInternals.h.
  static const size_t kMaxTotalInputSize = 10000000;

  const scoped_refptr<dom::Document> document_;
  const scoped_refptr<dom::Node> parent_node_;
  const scoped_refptr<dom::Node> reference_node_;
  // Max number the depth of the elements in the DOM tree. All elements at a
  // depth deeper than this will be discarded.
  const int dom_max_element_depth_;
  const base::SourceLocation first_chunk_location_;
  const base::Callback<void(const std::string&)> error_callback_;

  bool depth_limit_exceeded_;
  IssueSeverity max_severity_;
  size_t total_input_size_;

  std::string next_chunk_start_;
  std::stack<scoped_refptr<dom::Node> > node_stack_;

  DISALLOW_COPY_AND_ASSIGN(LibxmlParserWrapper);
};

}  // namespace dom_parser
}  // namespace cobalt

#endif  // COBALT_DOM_PARSER_LIBXML_PARSER_WRAPPER_H_
