/*
 * 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.
 */

#include "cobalt/dom_parser/libxml_xml_parser_wrapper.h"

#include "base/string_util.h"

namespace cobalt {
namespace dom_parser {
namespace {

// Libxml SAX handler.
//   http://www.xmlsoft.org/html/libxml-tree.html#xmlSAXHandler

// NOTE: Please read about XXE attacks before implementing handler fields such
// as resolveEntity and entityDecl.
xmlSAXHandler xml_sax_handler = {
    NULL,           /* internalSubset */
    NULL,           /* isStandalone */
    NULL,           /* hasInternalSubset */
    NULL,           /* hasExternalSubset */
    NULL,           /* resolveEntity */
    NULL,           /* getEntity */
    NULL,           /* entityDecl */
    NULL,           /* notationDecl */
    NULL,           /* attributeDecl */
    NULL,           /* elementDecl */
    NULL,           /* unparsedEntityDecl */
    NULL,           /* setDocumentLocator */
    &StartDocument, /* startDocument */
    &EndDocument,   /* endDocument */
    &StartElement,  /* startElement */
    &EndElement,    /* endElement */
    NULL,           /* reference */
    &Characters,    /* characters */
    NULL,           /* ignorableWhitespace */
    NULL,           /* processingInstruction */
    &Comment,       /* comment */
    &ParserWarning, /* xmlParserWarning */
    &ParserError,   /* xmlParserError */
    &ParserFatal,   /* xmlParserFatalError */
    NULL,           /* getParameterEntity */
    &CDATABlock,    /* cdataBlock */
    NULL,           /* externalSubset */
    1,              /* initialized */
    NULL,           /* private */
    NULL,           /* startElementNsSAX2Func */
    NULL,           /* endElementNsSAX2Func */
    NULL            /* xmlStructuredErrorFunc */
};

}  // namespace

//////////////////////////////////////////////////////////////////
// LibxmlXMLParserWrapper
//////////////////////////////////////////////////////////////////

LibxmlXMLParserWrapper::~LibxmlXMLParserWrapper() {
  if (xml_parser_context_) {
    xmlFreeParserCtxt(xml_parser_context_);
  }
}

void LibxmlXMLParserWrapper::DecodeChunk(const char* data, size_t size) {
  if (size == 0) {
    return;
  }

  if (!IsStringUTF8(std::string(data, size))) {
    static const char* kWarningNotUTF8 = "Ignoring non-UTF8 XML input.";
    OnParsingIssue(kWarning, kWarningNotUTF8);
    return;
  }

  if (!xml_parser_context_) {
    xml_parser_context_ =
        xmlCreatePushParserCtxt(&xml_sax_handler, this, data,
                                static_cast<int>(size), NULL /*filename*/);

    if (!xml_parser_context_) {
      static const char kErrorUnableCreateParser[] =
          "Unable to create the libxml2 parser.";
      OnParsingIssue(kFatal, kErrorUnableCreateParser);
    }
  } else {
    xmlParseChunk(xml_parser_context_, data, static_cast<int>(size),
                  0 /*do not terminate*/);
  }
}

void LibxmlXMLParserWrapper::Finish() {
  if (xml_parser_context_) {
    xmlParseChunk(xml_parser_context_, NULL, 0,
                  1 /*terminate*/);  // Triggers EndDocument
  }
}

base::SourceLocation LibxmlXMLParserWrapper::GetSourceLocation() {
  base::SourceLocation source_location(first_chunk_location().file_path,
                                       xml_parser_context_->input->line,
                                       xml_parser_context_->input->col);
  base::AdjustForStartLocation(
      first_chunk_location().line_number, first_chunk_location().column_number,
      &source_location.line_number, &source_location.column_number);
  return source_location;
}

}  // namespace dom_parser
}  // namespace cobalt
