// Copyright 2015 The Cobalt Authors. 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.

#include "cobalt/dom_parser/libxml_parser_wrapper.h"

#include "base/logging.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/third_party/icu/icu_utf.h"
#include "base/utf_string_conversion_utils.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/cdata_section.h"
#include "cobalt/dom/comment.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/text.h"
#if defined(OS_STARBOARD)
#include "starboard/configuration.h"
#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
#define HANDLE_CORE_DUMP
#include "base/lazy_instance.h"
#include "starboard/ps4/core_dump_handler.h"
#endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
#endif  // defined(OS_STARBOARD)
#include "third_party/libxml/src/include/libxml/xmlerror.h"

namespace cobalt {
namespace dom_parser {
namespace {

#if defined(HANDLE_CORE_DUMP)

class LibxmlParserWrapperLog {
 public:
  LibxmlParserWrapperLog()
      : total_parsed_bytes_(0),
        total_warning_count_(0),
        total_error_count_(0),
        total_fatal_count_(0) {
    SbCoreDumpRegisterHandler(CoreDumpHandler, this);
  }
  ~LibxmlParserWrapperLog() {
    SbCoreDumpUnregisterHandler(CoreDumpHandler, this);
  }

  static void CoreDumpHandler(void* context) {
    SbCoreDumpLogInteger(
        "LibxmlParserWrapper total parsed bytes",
        static_cast<LibxmlParserWrapperLog*>(context)->total_parsed_bytes_);
    SbCoreDumpLogInteger(
        "LibxmlParserWrapper total warning count",
        static_cast<LibxmlParserWrapperLog*>(context)->total_warning_count_);
    SbCoreDumpLogInteger(
        "LibxmlParserWrapper total error count",
        static_cast<LibxmlParserWrapperLog*>(context)->total_error_count_);
    SbCoreDumpLogInteger(
        "LibxmlParserWrapper total fatal error count",
        static_cast<LibxmlParserWrapperLog*>(context)->total_fatal_count_);
    SbCoreDumpLogString("LibxmlParserWrapper last fatal error",
                        static_cast<LibxmlParserWrapperLog*>(context)
                            ->last_fatal_message_.c_str());
  }

  void IncrementParsedBytes(int length) { total_parsed_bytes_ += length; }
  void LogParsingIssue(LibxmlParserWrapper::IssueSeverity severity,
                       const std::string& message) {
    if (severity == LibxmlParserWrapper::kWarning) {
      total_warning_count_++;
    } else if (severity == LibxmlParserWrapper::kError) {
      total_error_count_++;
    } else if (severity == LibxmlParserWrapper::kFatal) {
      total_fatal_count_++;
      last_fatal_message_ = message;
    } else {
      NOTREACHED();
    }
  }

 private:
  int total_parsed_bytes_;
  int total_warning_count_;
  int total_error_count_;
  int total_fatal_count_;
  std::string last_fatal_message_;
  DISALLOW_COPY_AND_ASSIGN(LibxmlParserWrapperLog);
};

base::LazyInstance<LibxmlParserWrapperLog> libxml_parser_wrapper_log =
    LAZY_INSTANCE_INITIALIZER;

#endif  // defined(HANDLE_CORE_DUMP)

/////////////////////////////////////////////////////////////////////////////
// Helpers
/////////////////////////////////////////////////////////////////////////////

LibxmlParserWrapper* ToLibxmlParserWrapper(void* context) {
  return reinterpret_cast<LibxmlParserWrapper*>(context);
}

const char* ToCString(const xmlChar* xmlstring) {
  // xmlChar*s are UTF-8, so this cast is safe.
  return reinterpret_cast<const char*>(xmlstring);
}

std::string StringPrintVAndTrim(const char* message, va_list arguments) {
  const std::string formatted_message = base::StringPrintV(message, arguments);

  std::string trimmed_message;
  TrimWhitespace(formatted_message, TRIM_ALL, &trimmed_message);

  return trimmed_message;
}

}  // namespace

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

void StartDocument(void* context) {
  ToLibxmlParserWrapper(context)->OnStartDocument();
}

void EndDocument(void* context) {
  ToLibxmlParserWrapper(context)->OnEndDocument();
}

void StartElement(void* context, const xmlChar* name,
                  const xmlChar** attribute_pairs) {
  LibxmlParserWrapper::ParserAttributeVector attributes;

  // attribute_pairs is an array of attribute pairs (name, value) terminated by
  // a pair of NULLs.
  if (attribute_pairs) {
    // Count the number of attributes and preallocate the attributes vectors.
    const xmlChar** end_attribute_pairs = attribute_pairs;
    while (end_attribute_pairs[0] || end_attribute_pairs[1]) {
      end_attribute_pairs += 2;
    }

    const size_t num_attributes =
        static_cast<size_t>((end_attribute_pairs - attribute_pairs) / 2);
    attributes.reserve(num_attributes);

    for (size_t i = 0; i < num_attributes; ++i, attribute_pairs += 2) {
      attributes.push_back(LibxmlParserWrapper::ParserAttribute(
          ToCString(attribute_pairs[0]), ToCString(attribute_pairs[1])));
    }
  }

  ToLibxmlParserWrapper(context)->OnStartElement(ToCString(name), attributes);
}

void EndElement(void* context, const xmlChar* name) {
  ToLibxmlParserWrapper(context)->OnEndElement(ToCString(name));
}

void Characters(void* context, const xmlChar* ch, int len) {
  ToLibxmlParserWrapper(context)
      ->OnCharacters(std::string(ToCString(ch), static_cast<size_t>(len)));
}

void Comment(void* context, const xmlChar* value) {
  ToLibxmlParserWrapper(context)->OnComment(ToCString(value));
}

void ParserWarning(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  ToLibxmlParserWrapper(context)->OnParsingIssue(
      LibxmlParserWrapper::kWarning, StringPrintVAndTrim(message, arguments));
}

void ParserError(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  ToLibxmlParserWrapper(context)->OnParsingIssue(
      LibxmlParserWrapper::kError, StringPrintVAndTrim(message, arguments));
}

void ParserFatal(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  ToLibxmlParserWrapper(context)->OnParsingIssue(
      LibxmlParserWrapper::kFatal, StringPrintVAndTrim(message, arguments));
}

void CDATABlock(void* context, const xmlChar* value, int len) {
  ToLibxmlParserWrapper(context)
      ->OnCDATABlock(std::string(ToCString(value), static_cast<size_t>(len)));
}

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

void LibxmlParserWrapper::OnStartDocument() { node_stack_.push(parent_node_); }

void LibxmlParserWrapper::OnEndDocument() {
  // Libxml can call OnEndDocument without calling OnStartDocument.
  if (node_stack_.empty()) {
    LOG(WARNING) << "OnEndDocument is called without OnStartDocument.";
  } else {
    while (parent_node_ != node_stack_.top()) {
      LOG(WARNING) << "some elements did not get called on OnEndElement()";
      node_stack_.pop();
    }
    DCHECK_GT(node_stack_.size(), static_cast<uint64_t>(0));
    DCHECK_EQ(parent_node_, node_stack_.top());
    node_stack_.pop();
  }

  if (!node_stack_.empty() && !error_callback_.is_null()) {
    error_callback_.Run("Node stack not empty at end of document.");
  }

  if (IsFullDocument()) {
    document_->PostToDispatchEvent(FROM_HERE, base::Tokens::domcontentloaded());
  }
}

void LibxmlParserWrapper::OnStartElement(
    const std::string& name, const ParserAttributeVector& attributes) {
  scoped_refptr<dom::Element> element = document_->CreateElement(name);
  for (size_t i = 0; i < attributes.size(); ++i) {
    element->SetAttribute(attributes[i].name.as_string(),
                          attributes[i].value.as_string());
  }

  if (static_cast<int>(node_stack_.size()) <= dom_max_element_depth_) {
    element->OnParserStartTag(GetSourceLocation());
    node_stack_.top()->InsertBefore(element, reference_node_);
  } else {
    if (!depth_limit_exceeded_) {
      depth_limit_exceeded_ = true;
      LOG(WARNING) << "Parser discarded deeply nested elements.";
    }
  }

  node_stack_.push(element);
}

void LibxmlParserWrapper::OnEndElement(const std::string& name) {
  while (!node_stack_.empty()) {
    scoped_refptr<dom::Element> element = node_stack_.top()->AsElement();
    node_stack_.pop();

    if (static_cast<int>(node_stack_.size()) <= dom_max_element_depth_) {
      element->OnParserEndTag();
    }

    if (element->local_name() == name) {
      return;
    }
  }
  if (node_stack_.empty() && !error_callback_.is_null()) {
    error_callback_.Run("Node stack empty when encountering end tag.");
  }
}

void LibxmlParserWrapper::OnCharacters(const std::string& value) {
  // The content of a sufficiently long text node can be provided as a sequence
  // of calls to OnCharacter.
  // If this is the first call in this sequence, a new Text node will be
  // create. Otherwise, the provided value will be appended to the previous
  // created Text node.
  scoped_refptr<dom::Node> last_child = node_stack_.top()->last_child();
  if (last_child && last_child->IsText() && !last_child->IsCDATASection()) {
    dom::Text* text = last_child->AsText();
    std::string data = text->data();
    data.append(value.data(), value.size());
    text->set_data(data);
  } else {
    node_stack_.top()->AppendChild(new dom::Text(document_, value));
  }
}

void LibxmlParserWrapper::OnComment(const std::string& comment) {
  node_stack_.top()->AppendChild(new dom::Comment(document_, comment));
}

void LibxmlParserWrapper::OnParsingIssue(IssueSeverity severity,
                                         const std::string& message) {
  DCHECK(severity >= kWarning && severity <= kFatal);

  xmlErrorPtr error = xmlGetLastError();
  if (error && error->code == XML_HTML_UNKNOWN_TAG) {
    return;
  }

  if (severity > max_severity_) {
    max_severity_ = severity;
  }
  if (severity < LibxmlParserWrapper::kFatal) {
    LOG(WARNING) << "Libxml "
                 << (severity == kWarning ? "Warning: " : "Error: ") << message;
  } else if (severity == LibxmlParserWrapper::kFatal) {
    LOG(ERROR) << "Libxml Fatal Error: " << message;
    if (!error_callback_.is_null()) {
      error_callback_.Run(message);
    }
  } else {
    NOTREACHED();
  }

#if defined(HANDLE_CORE_DUMP)
  libxml_parser_wrapper_log.Get().LogParsingIssue(severity, message);
#endif
}

void LibxmlParserWrapper::OnCDATABlock(const std::string& value) {
  node_stack_.top()->AppendChild(new dom::CDATASection(document_, value));
}

void LibxmlParserWrapper::PreprocessChunk(const char* data, size_t size,
                                          std::string* current_chunk) {
  DCHECK(current_chunk);
  // Check the total input size.
  total_input_size_ += size;
  if (total_input_size_ > kMaxTotalInputSize) {
    static const char kMessageInputTooLong[] = "Parser input is too long.";
    OnParsingIssue(kFatal, kMessageInputTooLong);
    return;
  }

  // Check the encoding of the input.
  std::string input = next_chunk_start_ + std::string(data, size);
  TruncateUTF8ToByteSize(input, input.size(), current_chunk);
  next_chunk_start_ = input.substr(current_chunk->size());
  if (!IsStringUTF8(*current_chunk)) {
    current_chunk->clear();
    static const char kMessageInputNotUTF8[] =
        "Parser input contains non-UTF8 characters.";
    OnParsingIssue(kFatal, kMessageInputNotUTF8);
    return;
  }

#if defined(HANDLE_CORE_DUMP)
  libxml_parser_wrapper_log.Get().IncrementParsedBytes(static_cast<int>(size));
#endif
}

}  // namespace dom_parser
}  // namespace cobalt
