// 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/parser.h"

#include "base/logging.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/xml_document.h"
#include "cobalt/dom_parser/html_decoder.h"
#include "cobalt/dom_parser/xml_decoder.h"

namespace cobalt {
namespace dom_parser {

scoped_refptr<dom::Document> Parser::ParseDocument(
    const std::string& input, dom::HTMLElementContext* html_element_context,
    const base::SourceLocation& input_location) {
  DCHECK(html_element_context);
  scoped_refptr<dom::Document> document =
      new dom::Document(html_element_context);
  HTMLDecoder html_decoder(document, document, NULL, dom_max_element_depth_,
                           input_location, base::Closure(), error_callback_,
                           false, require_csp_);
  html_decoder.DecodeChunk(input.c_str(), input.length());
  html_decoder.Finish();
  return document;
}

scoped_refptr<dom::XMLDocument> Parser::ParseXMLDocument(
    const std::string& input, dom::HTMLElementContext* html_element_context,
    const base::SourceLocation& input_location) {
  DCHECK(html_element_context);
  scoped_refptr<dom::XMLDocument> xml_document =
      new dom::XMLDocument(html_element_context);
  XMLDecoder xml_decoder(
      xml_document, xml_document, NULL, dom_max_element_depth_, input_location,
      base::Closure(),
      base::Bind(&Parser::ErrorCallback, base::Unretained(this)));
  xml_decoder.DecodeChunk(input.c_str(), input.length());
  xml_decoder.Finish();
  return xml_document;
}

void Parser::ParseDocumentFragment(
    const std::string& input, const scoped_refptr<dom::Document>& document,
    const scoped_refptr<dom::Node>& parent_node,
    const scoped_refptr<dom::Node>& reference_node,
    const base::SourceLocation& input_location) {
  HTMLDecoder html_decoder(
      document, parent_node, reference_node, dom_max_element_depth_,
      input_location, base::Closure(), error_callback_, false, require_csp_);
  html_decoder.DecodeChunk(input.c_str(), input.length());
  html_decoder.Finish();
}

void Parser::ParseXMLDocumentFragment(
    const std::string& input,
    const scoped_refptr<dom::XMLDocument>& xml_document,
    const scoped_refptr<dom::Node>& parent_node,
    const scoped_refptr<dom::Node>& reference_node,
    const base::SourceLocation& input_location) {
  XMLDecoder xml_decoder(
      xml_document, parent_node, reference_node, dom_max_element_depth_,
      input_location, base::Closure(),
      base::Bind(&Parser::ErrorCallback, base::Unretained(this)));
  xml_decoder.DecodeChunk(input.c_str(), input.length());
  xml_decoder.Finish();
}

scoped_ptr<loader::Decoder> Parser::ParseDocumentAsync(
    const scoped_refptr<dom::Document>& document,
    const base::SourceLocation& input_location) {
  return scoped_ptr<loader::Decoder>(new HTMLDecoder(
      document, document, NULL, dom_max_element_depth_, input_location,
      base::Closure(), error_callback_, true, require_csp_));
}

scoped_ptr<loader::Decoder> Parser::ParseXMLDocumentAsync(
    const scoped_refptr<dom::XMLDocument>& xml_document,
    const base::SourceLocation& input_location) {
  return scoped_ptr<loader::Decoder>(
      new XMLDecoder(xml_document, xml_document, NULL, dom_max_element_depth_,
                     input_location, base::Closure(), error_callback_));
}

void Parser::ErrorCallback(const std::string& error) {
  LOG(ERROR) << "Error in DOM parsing: " << error;
}

}  // namespace dom_parser
}  // namespace cobalt
