/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All
 * rights reserved.
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * 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 "third_party/blink/renderer/core/dom/document_init.h"

#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/sink_document.h"
#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/html_view_source_document.h"
#include "third_party/blink/renderer/core/html/image_document.h"
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/media_document.h"
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/html/text_document.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/plugin_data.h"
#include "third_party/blink/renderer/platform/network/mime/content_type.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"

namespace blink {

// static
DocumentInit DocumentInit::Create() {
  return DocumentInit();
}

DocumentInit::DocumentInit(const DocumentInit&) = default;

DocumentInit::~DocumentInit() = default;

DocumentInit& DocumentInit::ForTest() {
  DCHECK(!execution_context_);
  DCHECK(!window_);
#if DCHECK_IS_ON()
  DCHECK(!for_test_);
  for_test_ = true;
#endif
  return *this;
}

DocumentInit& DocumentInit::WithImportsController(
    HTMLImportsController* controller) {
  imports_controller_ = controller;
  return *this;
}

bool DocumentInit::ShouldSetURL() const {
  return (window_ && !window_->GetFrame()->IsMainFrame()) || !url_.IsEmpty();
}

bool DocumentInit::IsSrcdocDocument() const {
  return window_ && !window_->GetFrame()->IsMainFrame() && is_srcdoc_document_;
}

DocumentInit& DocumentInit::WithWindow(LocalDOMWindow* window,
                                       Document* owner_document) {
  DCHECK(!window_);
  DCHECK(!execution_context_);
  DCHECK(!imports_controller_);
#if DCHECK_IS_ON()
  DCHECK(!for_test_);
#endif
  DCHECK(window);
  window_ = window;
  execution_context_ = window;
  owner_document_ = owner_document;
  return *this;
}

DocumentInit& DocumentInit::ForInitialEmptyDocument(bool empty) {
  is_initial_empty_document_ = empty;
  return *this;
}

DocumentInit& DocumentInit::ForPrerendering(bool is_prerendering) {
  is_prerendering_ = is_prerendering;
  return *this;
}

// static
DocumentInit::Type DocumentInit::ComputeDocumentType(
    LocalFrame* frame,
    const KURL& url,
    const String& mime_type,
    bool* is_for_external_handler) {
  if (frame && frame->InViewSourceMode())
    return Type::kViewSource;

  // Plugins cannot take HTML and XHTML from us, and we don't even need to
  // initialize the plugin database for those.
  if (mime_type == "text/html")
    return Type::kHTML;

  if (mime_type == "application/xhtml+xml")
    return Type::kXHTML;

  // multipart/x-mixed-replace is only supported for images.
  if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(mime_type) ||
      mime_type == "multipart/x-mixed-replace") {
    return Type::kImage;
  }

  if (HTMLMediaElement::GetSupportsType(ContentType(mime_type)))
    return Type::kMedia;

  if (frame && frame->GetPage() && frame->Loader().AllowPlugins()) {
    PluginData* plugin_data = GetPluginData(frame, url);

    // Everything else except text/plain can be overridden by plugins.
    // 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 (mime_type != "text/plain" && plugin_data &&
        plugin_data->SupportsMimeType(mime_type)) {
      // Plugins handled by MimeHandlerView do not create a PluginDocument. They
      // are rendered inside cross-process frames and the notion of a PluginView
      // (which is associated with PluginDocument) is irrelevant here.
      if (plugin_data->IsExternalPluginMimeType(mime_type)) {
        if (is_for_external_handler)
          *is_for_external_handler = true;
        return Type::kHTML;
      }

      return Type::kPlugin;
    }
  }

  if (MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type) ||
      MIMETypeRegistry::IsJSONMimeType(mime_type) ||
      MIMETypeRegistry::IsPlainTextMIMEType(mime_type)) {
    return Type::kText;
  }

  if (mime_type == "image/svg+xml")
    return Type::kSVG;

  if (MIMETypeRegistry::IsXMLMIMEType(mime_type))
    return Type::kXML;

  return Type::kHTML;
}

// static
PluginData* DocumentInit::GetPluginData(LocalFrame* frame, const KURL& url) {
  // If the document is being created for the main frame,
  // frame()->tree().top()->securityContext() returns nullptr.
  // For that reason, the origin must be retrieved directly from |url|.
  if (frame->IsMainFrame())
    return frame->GetPage()->GetPluginData(SecurityOrigin::Create(url).get());

  const SecurityOrigin* main_frame_origin =
      frame->Tree().Top().GetSecurityContext()->GetSecurityOrigin();
  return frame->GetPage()->GetPluginData(main_frame_origin);
}

DocumentInit& DocumentInit::WithTypeFrom(const String& mime_type) {
  mime_type_ = mime_type;
  type_ = ComputeDocumentType(window_ ? window_->GetFrame() : nullptr, Url(),
                              mime_type_, &is_for_external_handler_);
  return *this;
}

DocumentInit& DocumentInit::WithExecutionContext(
    ExecutionContext* execution_context) {
  DCHECK(!execution_context_);
  DCHECK(!window_);
#if DCHECK_IS_ON()
  DCHECK(!for_test_);
#endif
  execution_context_ = execution_context;
  return *this;
}

DocumentInit& DocumentInit::WithURL(const KURL& url) {
  DCHECK(url_.IsNull());
  url_ = url;
  return *this;
}

const KURL& DocumentInit::GetCookieUrl() const {
  const KURL& cookie_url =
      owner_document_ ? owner_document_->CookieURL() : url_;

  // An "about:blank" should inherit the `cookie_url` from the initiator of the
  // navigation, but sometimes "about:blank" may commit without an
  // `owner_document` (e.g. if the original initiator has been navigated away).
  // In such scenario, it is important to use a safe `cookie_url` (e.g.
  // kCookieAverseUrl) to avoid triggering mojo::ReportBadMessage and renderer
  // kills via RestrictedCookieManager::ValidateAccessToCookiesAt.
  //
  // TODO(https://crbug.com/1176291): Correctly inherit the `cookie_url` from
  // the initiator.
  if (cookie_url.IsAboutBlankURL()) {
    // Signify a cookie-averse document [1] with an null URL.  See how
    // CookiesJar::GetCookies and other methods check `cookie_url` against
    // KURL::IsEmpty.
    //
    // [1] https://html.spec.whatwg.org/#cookie-averse-document-object
    const KURL& kCookieAverseUrl = NullURL();

    return kCookieAverseUrl;
  }

  return cookie_url;
}

DocumentInit& DocumentInit::WithSrcdocDocument(bool is_srcdoc_document) {
  is_srcdoc_document_ = is_srcdoc_document;
  return *this;
}


DocumentInit& DocumentInit::WithWebBundleClaimedUrl(
    const KURL& web_bundle_claimed_url) {
  web_bundle_claimed_url_ = web_bundle_claimed_url;
  return *this;
}

DocumentInit& DocumentInit::WithUkmSourceId(ukm::SourceId ukm_source_id) {
  ukm_source_id_ = ukm_source_id;
  return *this;
}

Document* DocumentInit::CreateDocument() const {
#if DCHECK_IS_ON()
  DCHECK(execution_context_ || for_test_);
#endif
  switch (type_) {
    case Type::kHTML:
      return MakeGarbageCollected<HTMLDocument>(*this);
    case Type::kXHTML:
      return XMLDocument::CreateXHTML(*this);
    case Type::kImage:
      return MakeGarbageCollected<ImageDocument>(*this);
    case Type::kPlugin: {
      DCHECK(window_);
      if (window_->IsSandboxed(
              network::mojom::blink::WebSandboxFlags::kPlugins)) {
        return MakeGarbageCollected<SinkDocument>(*this);
      }
      return MakeGarbageCollected<PluginDocument>(*this);
    }
    case Type::kMedia:
      return MakeGarbageCollected<MediaDocument>(*this);
    case Type::kSVG:
      return XMLDocument::CreateSVG(*this);
    case Type::kXML:
      return MakeGarbageCollected<XMLDocument>(*this);
    case Type::kViewSource:
      return MakeGarbageCollected<HTMLViewSourceDocument>(*this);
    case Type::kText:
      return MakeGarbageCollected<TextDocument>(*this);
    case Type::kUnspecified:
      FALLTHROUGH;
    default:
      break;
  }
  NOTREACHED();
  return nullptr;
}

}  // namespace blink
