/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "core/dom/DOMImplementation.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/HTMLNames.h"
#include "core/SVGNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/ContextFeatures.h"
#include "core/dom/DocumentInit.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/Text.h"
#include "core/dom/XMLDocument.h"
#include "core/dom/custom/V0CustomElementRegistrationContext.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/UseCounter.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLTitleElement.h"
#include "core/html/HTMLViewSourceDocument.h"
#include "core/html/ImageDocument.h"
#include "core/html/MediaDocument.h"
#include "core/html/PluginDocument.h"
#include "core/html/TextDocument.h"
#include "core/loader/FrameLoader.h"
#include "core/page/Page.h"
#include "platform/ContentType.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/graphics/Image.h"
#include "platform/plugins/PluginData.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/StdLibExtras.h"

namespace blink {

DOMImplementation::DOMImplementation(Document& document)
    : m_document(document) {}

DocumentType* DOMImplementation::createDocumentType(
    const AtomicString& qualifiedName,
    const String& publicId,
    const String& systemId,
    ExceptionState& exceptionState) {
  AtomicString prefix, localName;
  if (!Document::parseQualifiedName(qualifiedName, prefix, localName,
                                    exceptionState))
    return nullptr;

  return DocumentType::create(m_document, qualifiedName, publicId, systemId);
}

XMLDocument* DOMImplementation::createDocument(
    const AtomicString& namespaceURI,
    const AtomicString& qualifiedName,
    DocumentType* doctype,
    ExceptionState& exceptionState) {
  XMLDocument* doc = nullptr;
  DocumentInit init = DocumentInit::fromContext(document().contextDocument());
  if (namespaceURI == SVGNames::svgNamespaceURI) {
    doc = XMLDocument::createSVG(init);
  } else if (namespaceURI == HTMLNames::xhtmlNamespaceURI) {
    doc = XMLDocument::createXHTML(
        init.withRegistrationContext(document().registrationContext()));
  } else {
    doc = XMLDocument::create(init);
  }

  doc->setSecurityOrigin(document().getSecurityOrigin());
  doc->setContextFeatures(document().contextFeatures());

  Node* documentElement = nullptr;
  if (!qualifiedName.isEmpty()) {
    documentElement =
        doc->createElementNS(namespaceURI, qualifiedName, exceptionState);
    if (exceptionState.hadException())
      return nullptr;
  }

  if (doctype)
    doc->appendChild(doctype);
  if (documentElement)
    doc->appendChild(documentElement);

  return doc;
}

bool DOMImplementation::isXMLMIMEType(const String& mimeType) {
  if (equalIgnoringCase(mimeType, "text/xml") ||
      equalIgnoringCase(mimeType, "application/xml") ||
      equalIgnoringCase(mimeType, "text/xsl"))
    return true;

  // Per RFCs 3023 and 2045, an XML MIME type is of the form:
  // ^[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+/[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+\+xml$

  int length = mimeType.length();
  if (length < 7)
    return false;

  if (mimeType[0] == '/' || mimeType[length - 5] == '/' ||
      !mimeType.endsWith("+xml", TextCaseInsensitive))
    return false;

  bool hasSlash = false;
  for (int i = 0; i < length - 4; ++i) {
    UChar ch = mimeType[i];
    if (ch >= '0' && ch <= '9')
      continue;
    if (ch >= 'a' && ch <= 'z')
      continue;
    if (ch >= 'A' && ch <= 'Z')
      continue;
    switch (ch) {
      case '_':
      case '-':
      case '+':
      case '~':
      case '!':
      case '$':
      case '^':
      case '{':
      case '}':
      case '|':
      case '.':
      case '%':
      case '\'':
      case '`':
      case '#':
      case '&':
      case '*':
        continue;
      case '/':
        if (hasSlash)
          return false;
        hasSlash = true;
        continue;
      default:
        return false;
    }
  }

  return true;
}

bool DOMImplementation::isJSONMIMEType(const String& mimeType) {
  if (mimeType.startsWith("application/json", TextCaseInsensitive))
    return true;
  if (mimeType.startsWith("application/", TextCaseInsensitive)) {
    size_t subtype = mimeType.find("+json", 12, TextCaseInsensitive);
    if (subtype != kNotFound) {
      // Just check that a parameter wasn't matched.
      size_t parameterMarker = mimeType.find(";");
      if (parameterMarker == kNotFound) {
        unsigned endSubtype = static_cast<unsigned>(subtype) + 5;
        return endSubtype == mimeType.length() ||
               isASCIISpace(mimeType[endSubtype]);
      }
      return parameterMarker > subtype;
    }
  }
  return false;
}

static bool isTextPlainType(const String& mimeType) {
  return mimeType.startsWith("text/", TextCaseInsensitive) &&
         !(equalIgnoringCase(mimeType, "text/html") ||
           equalIgnoringCase(mimeType, "text/xml") ||
           equalIgnoringCase(mimeType, "text/xsl"));
}

bool DOMImplementation::isTextMIMEType(const String& mimeType) {
  return MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) ||
         isJSONMIMEType(mimeType) || isTextPlainType(mimeType);
}

HTMLDocument* DOMImplementation::createHTMLDocument(const String& title) {
  DocumentInit init =
      DocumentInit::fromContext(document().contextDocument())
          .withRegistrationContext(document().registrationContext());
  HTMLDocument* d = HTMLDocument::create(init);
  d->open();
  d->write("<!doctype html><html><head></head><body></body></html>");
  if (!title.isNull()) {
    HTMLHeadElement* headElement = d->head();
    DCHECK(headElement);
    HTMLTitleElement* titleElement = HTMLTitleElement::create(*d);
    headElement->appendChild(titleElement);
    titleElement->appendChild(d->createTextNode(title), ASSERT_NO_EXCEPTION);
  }
  d->setSecurityOrigin(document().getSecurityOrigin());
  d->setContextFeatures(document().contextFeatures());
  return d;
}

Document* DOMImplementation::createDocument(const String& type,
                                            const DocumentInit& init,
                                            bool inViewSourceMode) {
  if (inViewSourceMode)
    return HTMLViewSourceDocument::create(init, type);

  // Plugins cannot take HTML and XHTML from us, and we don't even need to
  // initialize the plugin database for those.
  if (type == "text/html")
    return HTMLDocument::create(init);
  if (type == "application/xhtml+xml")
    return XMLDocument::createXHTML(init);

  PluginData* pluginData = nullptr;
  if (init.frame() && init.frame()->page() &&
      init.frame()->loader().allowPlugins(NotAboutToInstantiatePlugin)) {
    // If the document is being created for the main frame,
    // init.frame()->tree().top()->securityContext() returns nullptr.
    // For that reason, the origin must be retrieved directly from init.url().
    if (init.frame()->isMainFrame()) {
      RefPtr<SecurityOrigin> origin = SecurityOrigin::create(init.url());
      pluginData = init.frame()->page()->pluginData(origin.get());
    } else {
      pluginData = init.frame()->page()->pluginData(
          init.frame()->tree().top()->securityContext()->getSecurityOrigin());
    }
  }

  // PDF is one image type for which a plugin can override built-in support.
  // We do not want QuickTime to take over all image types, obviously.
  if ((type == "application/pdf" || type == "text/pdf") && pluginData &&
      pluginData->supportsMimeType(type))
    return PluginDocument::create(init);
  // multipart/x-mixed-replace is only supported for images.
  if (Image::supportsType(type) || type == "multipart/x-mixed-replace")
    return ImageDocument::create(init);

  // Check to see if the type can be played by our media player, if so create a
  // MediaDocument
  if (HTMLMediaElement::supportsType(ContentType(type)))
    return MediaDocument::create(init);

  // Everything else except text/plain can be overridden by plugins. In
  // particular, Adobe SVG Viewer should be used for SVG, if installed.
  // Disallowing plugins to use text/plain prevents plugins from hijacking a
  // fundamental type that the browser is expected to handle, and also serves as
  // an optimization to prevent loading the plugin database in the common case.
  if (type != "text/plain" && pluginData && pluginData->supportsMimeType(type))
    return PluginDocument::create(init);
  if (isTextMIMEType(type))
    return TextDocument::create(init);
  if (type == "image/svg+xml")
    return XMLDocument::createSVG(init);
  if (isXMLMIMEType(type))
    return XMLDocument::create(init);

  return HTMLDocument::create(init);
}

DEFINE_TRACE(DOMImplementation) {
  visitor->trace(m_document);
}

}  // namespace blink
