/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.Chromium file.

#include "web_contents_delegate_qt.h"

#include "profile_adapter.h"
#include "color_chooser_controller.h"
#include "color_chooser_qt.h"
#include "favicon_manager.h"
#include "file_picker_controller.h"
#include "media_capture_devices_dispatcher.h"
#include "net/network_delegate_qt.h"
#include "profile_qt.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
#include "register_protocol_handler_request_controller_impl.h"
#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
#include "web_contents_adapter_client.h"
#include "web_contents_adapter.h"
#include "web_contents_view_qt.h"
#include "web_engine_context.h"
#include "web_engine_settings.h"

#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/favicon_url.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "net/base/data_url.h"
#include "net/base/url_util.h"

#include <QDesktopServices>
#include <QTimer>
#include <QWindow>

namespace QtWebEngineCore {

static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptConsoleMessageLevel(blink::mojom::ConsoleMessageLevel log_level)
{
    switch (log_level) {
    case blink::mojom::ConsoleMessageLevel::kVerbose:
    case blink::mojom::ConsoleMessageLevel::kInfo:
        return WebContentsAdapterClient::Info;
    case blink::mojom::ConsoleMessageLevel::kWarning:
        return WebContentsAdapterClient::Warning;
    case blink::mojom::ConsoleMessageLevel::kError:
        return WebContentsAdapterClient::Error;
    }
}

WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
    : m_viewClient(adapterClient)
    , m_faviconManager(new FaviconManager(webContents, adapterClient))
    , m_findTextHelper(new FindTextHelper(webContents, adapterClient))
    , m_lastLoadProgress(-1)
    , m_loadingState(determineLoadingState(webContents))
    , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
    , m_frameFocusedObserver(adapterClient)
{
    webContents->SetDelegate(this);
    Observe(webContents);
}

WebContentsDelegateQt::~WebContentsDelegateQt()
{
    // The destruction of this object should take place before
    // WebContents destruction since WebContentsAdapterClient
    // might be already deleted.
}

content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params)
{
    content::WebContents *target = source;
    content::SiteInstance *target_site_instance = params.source_site_instance.get();
    content::Referrer referrer = params.referrer;
    if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
        QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture);
        if (targetAdapter) {
            if (targetAdapter->profile() != source->GetBrowserContext()) {
                target_site_instance = nullptr;
                referrer = content::Referrer();
            }
            if (!targetAdapter->isInitialized())
                targetAdapter->initialize(target_site_instance);
            target = targetAdapter->webContents();
        }
    }
    Q_ASSERT(target);

    content::NavigationController::LoadURLParams load_url_params(params.url);
    load_url_params.initiator_origin = params.initiator_origin;
    load_url_params.source_site_instance = target_site_instance;
    load_url_params.referrer = referrer;
    load_url_params.frame_tree_node_id = params.frame_tree_node_id;
    load_url_params.redirect_chain = params.redirect_chain;
    load_url_params.transition_type = params.transition;
    load_url_params.extra_headers = params.extra_headers;
    load_url_params.should_replace_current_entry = params.should_replace_current_entry;
    load_url_params.is_renderer_initiated = params.is_renderer_initiated;
    load_url_params.started_from_context_menu = params.started_from_context_menu;
    load_url_params.has_user_gesture = params.user_gesture;
    load_url_params.blob_url_loader_factory = params.blob_url_loader_factory;
    load_url_params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
    load_url_params.href_translate = params.href_translate;
    load_url_params.reload_type = params.reload_type;
    if (params.uses_post) {
        load_url_params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST;
        load_url_params.post_data = params.post_data;
    }

    target->GetController().LoadURLWithParams(load_url_params);
    return target;
}

static bool shouldUseActualURL(content::NavigationEntry *entry)
{
    Q_ASSERT(entry);

    // Show actual URL for data URLs only
    if (!entry->GetURL().SchemeIs(url::kDataScheme))
        return false;

    // Do not show data URL of interstitial and error pages
    if (entry->GetPageType() != content::PAGE_TYPE_NORMAL)
        return false;

    // Show invalid data URL
    std::string mime_type, charset, data;
    if (!net::DataURL::Parse(entry->GetURL(), &mime_type, &charset, &data))
        return false;

    // Do not show empty data URL
    return !data.empty();
}

void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags)
{
    if (changed_flags & content::INVALIDATE_TYPE_URL && !m_pendingUrlUpdate) {
        m_pendingUrlUpdate = true;
        base::WeakPtr<WebContentsDelegateQt> delegate = AsWeakPtr();
        QTimer::singleShot(0, [delegate, this](){ if (delegate) m_viewClient->urlChanged();});
    }

    if (changed_flags & content::INVALIDATE_TYPE_TITLE) {
        QString newTitle = toQt(source->GetTitle());
        if (m_title != newTitle) {
            m_title = newTitle;
            m_viewClient->titleChanged(m_title);
        }
    }

    // NavigationStateChanged gets called with INVALIDATE_TYPE_TAB by AudioStateProvider::Notify,
    // whenever an audio sound gets played or stopped, this is the only way to actually figure out
    // if there was a recently played audio sound.
    // Make sure to only emit the signal when loading isn't in progress, because it causes multiple
    // false signals to be emitted.
    if ((changed_flags & content::INVALIDATE_TYPE_TAB) && !(changed_flags & content::INVALIDATE_TYPE_LOAD)) {
        m_viewClient->recentlyAudibleChanged(source->IsCurrentlyAudible());
    }
}

QUrl WebContentsDelegateQt::url(content::WebContents* source) const {

    content::NavigationEntry *entry = source->GetController().GetVisibleEntry();
    QUrl newUrl;
    if (entry) {
        GURL url = entry->GetURL();
        // Strip user name, password and reference section from view-source URLs
        if (source->GetVisibleURL().SchemeIs(content::kViewSourceScheme) &&
            (url.has_password() || url.has_username() || url.has_ref())) {
            GURL strippedUrl = net::SimplifyUrlForRequest(url);
            newUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme, QString::fromStdString(strippedUrl.spec())));
        }
        // If there is a visible entry there are special cases when we dont wan't to use the actual URL
        if (newUrl.isEmpty())
            newUrl = shouldUseActualURL(entry) ? toQt(url) : toQt(entry->GetVirtualURL());
    }
    m_pendingUrlUpdate = false;
    return newUrl;
}
void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
{
    Q_UNUSED(source)
    QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, user_gesture);
    // Chromium can forget to pass user-agent override settings to new windows (see QTBUG-61774 and QTBUG-76249),
    // so set it here. Note the actual value doesn't really matter here. Only the second value does, but we try
    // to give the correct user-agent anyway.
    if (newAdapter)
        newAdapter->webContents()->SetUserAgentOverride(newAdapter->profileAdapter()->httpUserAgent().toStdString(), true);
    if (newAdapter && !newAdapter->isInitialized())
        newAdapter->loadDefault();
    if (was_blocked)
        *was_blocked = !newAdapter;
}

void WebContentsDelegateQt::CloseContents(content::WebContents *source)
{
    m_viewClient->close();
    GetJavaScriptDialogManager(source)->CancelDialogs(source, /* whatever?: */false);
}

void WebContentsDelegateQt::LoadProgressChanged(content::WebContents */*source*/, double progress)
{
    if (!m_loadingErrorFrameList.isEmpty())
        return;
    if (m_lastLoadProgress < 0) // suppress signals that aren't between loadStarted and loadFinished
        return;
    m_lastLoadProgress = qMax(m_lastLoadProgress, qRound(progress * 100)); // ensure monotonicity
    m_lastLoadProgress = qMin(m_lastLoadProgress, 100);
    m_viewClient->loadProgressChanged(m_lastLoadProgress);
}

bool WebContentsDelegateQt::HandleKeyboardEvent(content::WebContents *, const content::NativeWebKeyboardEvent &event)
{
    Q_ASSERT(!event.skip_in_browser);
    if (event.os_event)
        m_viewClient->unhandledKeyEvent(reinterpret_cast<QKeyEvent *>(event.os_event));
    // FIXME: ?
    return true;
}

void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host)
{
    content::FrameTreeNode *node = static_cast<content::RenderFrameHostImpl *>(render_frame_host)->frame_tree_node();
    m_frameFocusedObserver.addNode(node);
}

void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
{
    m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
}

void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
{
    // RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
    if (status != base::TERMINATION_STATUS_STILL_RUNNING) {
        m_viewClient->renderProcessTerminated(
                m_viewClient->renderProcessExitStatus(status),
                web_contents()->GetCrashedErrorCode());
    }

    // Based one TabLoadTracker::RenderProcessGone

    if (status == base::TERMINATION_STATUS_NORMAL_TERMINATION
        || status == base::TERMINATION_STATUS_STILL_RUNNING) {
        return;
    }

    setLoadingState(LoadingState::Unloaded);
}

void WebContentsDelegateQt::RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host)
{
    if (old_host) {
        content::FrameTreeNode *old_node = static_cast<content::RenderFrameHostImpl *>(old_host)->frame_tree_node();
        m_frameFocusedObserver.removeNode(old_node);
    }

    if (new_host) {
        content::FrameTreeNode *new_node = static_cast<content::RenderFrameHostImpl *>(new_host)->frame_tree_node();
        m_frameFocusedObserver.addNode(new_node);
    }
}

void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *newHost)
{
    if (newHost && newHost->GetWidget() && newHost->GetWidget()->GetView()) {
        auto rwhv = static_cast<RenderWidgetHostViewQt *>(newHost->GetWidget()->GetView());
        m_viewClient->widgetChanged(rwhv->delegate());
    }
}

void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage)
{
    if (m_lastLoadProgress >= 0 && m_lastLoadProgress < 100) // already running
        return;
    m_viewClient->loadStarted(url, isErrorPage);
    m_viewClient->updateNavigationActions();
    m_viewClient->loadProgressChanged(0);
    m_lastLoadProgress = 0;
}

void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
{
    if (!navigation_handle->IsInMainFrame())
        return;

    // Error-pages are not reported as separate started navigations.
    Q_ASSERT(!navigation_handle->IsErrorPage());

    m_loadingErrorFrameList.clear();
    m_faviconManager->resetCandidates();
    EmitLoadStarted(toQt(navigation_handle->GetURL()));
}

void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
{
    if (m_lastLoadProgress < 0) // not currently running
        return;
    m_lastLoadProgress = -1;
    m_viewClient->loadProgressChanged(100);
    m_viewClient->loadFinished(success, url, isErrorPage, errorCode, errorDescription);
    m_viewClient->updateNavigationActions();
}

void WebContentsDelegateQt::EmitLoadCommitted()
{
    m_findTextHelper->handleLoadCommitted();
    m_viewClient->loadCommitted();
    m_viewClient->updateNavigationActions();
}

void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navigation_handle)
{
    if (!navigation_handle->IsInMainFrame())
        return;

    if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
        ProfileAdapter *profileAdapter = m_viewClient->profileAdapter();
        // VisistedLinksMaster asserts !IsOffTheRecord().
        if (navigation_handle->ShouldUpdateHistory() && profileAdapter->trackVisitedLinks()) {
            for (const GURL &url : navigation_handle->GetRedirectChain())
                profileAdapter->visitedLinksManager()->addUrl(url);
        }

        EmitLoadCommitted();
    }
    // Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below
    if (navigation_handle->GetNetErrorCode() == net::OK)
        return;

    // WebContentsObserver::DidFailLoad is not called any longer so we have to report the failure here.
    const net::Error error_code = navigation_handle->GetNetErrorCode();
    const std::string error_description = net::ErrorToString(error_code);
    didFailLoad(toQt(navigation_handle->GetURL()), error_code, toQt(error_description));

    // The load will succede as an error-page load later, and we reported the original error above
    if (navigation_handle->IsErrorPage()) {
        // Now report we are starting to load an error-page.
        m_loadingErrorFrameList.append(navigation_handle->GetRenderFrameHost()->GetRoutingID());
        m_faviconManager->resetCandidates();
        EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);

        // If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call.
        if (navigation_handle->HasCommitted())
            EmitLoadCommitted();
    }
}

void WebContentsDelegateQt::DidStartLoading()
{
    // Based on TabLoadTracker::DidStartLoading

    if (!web_contents()->IsLoadingToDifferentDocument())
        return;
    if (m_loadingState == LoadingState::Loading) {
        DCHECK(m_didStartLoadingSeen);
        return;
    }
    m_didStartLoadingSeen = true;
}

void WebContentsDelegateQt::DidReceiveResponse()
{
    // Based on TabLoadTracker::DidReceiveResponse

    if (m_loadingState == LoadingState::Loading) {
        DCHECK(m_didStartLoadingSeen);
        return;
    }

    // A transition to loading requires both DidStartLoading (navigation
    // committed) and DidReceiveResponse (data has been transmitted over the
    // network) events to occur. This is because NavigationThrottles can block
    // actual network requests, but not the rest of the state machinery.
    if (m_didStartLoadingSeen)
        setLoadingState(LoadingState::Loading);
}

void WebContentsDelegateQt::DidStopLoading()
{
    // Based on TabLoadTracker::DidStopLoading

    // NOTE: PageAlmostIdle feature not implemented

    if (m_loadingState == LoadingState::Loading)
        setLoadingState(LoadingState::Loaded);
}

void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
{
    m_viewClient->iconChanged(QUrl());
    EmitLoadFinished(false /* success */ , url, false /* isErrorPage */, errorCode, errorDescription);
}

void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description)
{
    if (m_loadingState == LoadingState::Loading)
        setLoadingState(LoadingState::Loaded);

    if (render_frame_host != web_contents()->GetMainFrame())
        return;

    if (validated_url.spec() == content::kUnreachableWebDataURL) {
        // error-pages should only ever fail due to abort:
        Q_ASSERT(error_code == -3 /* ERR_ABORTED */);
        m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
        m_viewClient->iconChanged(QUrl());

        EmitLoadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */);
        return;
    }

    didFailLoad(toQt(validated_url), error_code, toQt(error_description));
}

void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url)
{
    Q_ASSERT(validated_url.is_valid());
    if (validated_url.spec() == content::kUnreachableWebDataURL) {
        m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
        m_viewClient->iconChanged(QUrl());

        // Trigger LoadFinished signal for main frame's error page only.
        if (!render_frame_host->GetParent())
            EmitLoadFinished(true /* success */, toQt(validated_url), true /* isErrorPage */);

        return;
    }

    if (render_frame_host->GetParent())
        return;

    if (!m_faviconManager->hasCandidate())
        m_viewClient->iconChanged(QUrl());

    content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry();
    int http_statuscode = 0;
    if (entry)
       http_statuscode = entry->GetHttpStatusCode();
    EmitLoadFinished(true /* success */ , toQt(validated_url), false /* isErrorPage */, http_statuscode);
}

void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates)
{
    QList<FaviconInfo> faviconCandidates;
    faviconCandidates.reserve(static_cast<int>(candidates.size()));
    for (const content::FaviconURL &candidate : candidates) {
        // Store invalid candidates too for later debugging via API
        faviconCandidates.append(toFaviconInfo(candidate));
    }

    // Favicon URL can be changed from JavaScript too. Thus we need to reset
    // the current candidate icon list to not handle previous icon as a candidate.
    m_faviconManager->resetCandidates();
    m_faviconManager->update(faviconCandidates);
}

void WebContentsDelegateQt::WebContentsCreated(content::WebContents * /*source_contents*/,
                                               int /*opener_render_process_id*/, int /*opener_render_frame_id*/,
                                               const std::string &/*frame_name*/,
                                               const GURL &target_url, content::WebContents *newContents)
{
    m_initialTargetUrl = toQt(target_url);
    if (auto *view = static_cast<content::WebContentsImpl *>(newContents)->GetView())
        static_cast<WebContentsViewQt *>(view)->setFactoryClient(m_viewClient);
}

content::ColorChooser *WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestion)
{
    Q_UNUSED(suggestion);
    ColorChooserQt *colorChooser = new ColorChooserQt(source, toQt(color));
    m_viewClient->showColorDialog(colorChooser->controller());

    return colorChooser;
}
content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogManager(content::WebContents *)
{
    return JavaScriptDialogManagerQt::GetInstance();
}

void WebContentsDelegateQt::EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL& origin, const blink::WebFullscreenOptions &)
{
    Q_UNUSED(web_contents);
    if (!m_viewClient->isFullScreenMode())
        m_viewClient->requestFullScreenMode(toQt(origin), true);
}

void WebContentsDelegateQt::ExitFullscreenModeForTab(content::WebContents *web_contents)
{
    if (m_viewClient->isFullScreenMode())
        m_viewClient->requestFullScreenMode(toQt(web_contents->GetLastCommittedURL().GetOrigin()), false);
}

bool WebContentsDelegateQt::IsFullscreenForTabOrPending(const content::WebContents* web_contents)
{
    Q_UNUSED(web_contents);
    return m_viewClient->isFullScreenMode();
}

ASSERT_ENUMS_MATCH(FilePickerController::Open, blink::mojom::FileChooserParams::Mode::kOpen)
ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, blink::mojom::FileChooserParams::Mode::kOpenMultiple)
ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, blink::mojom::FileChooserParams::Mode::kUploadFolder)
ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams::Mode::kSave)

void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHost*/,
                                           std::unique_ptr<content::FileSelectListener> listener,
                                           const blink::mojom::FileChooserParams& params)
{
    QStringList acceptedMimeTypes;
    acceptedMimeTypes.reserve(params.accept_types.size());
    for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it)
        acceptedMimeTypes.append(toQt(*it));

    m_filePickerController.reset(new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode),
                                                          std::move(listener), toQt(params.default_file_name.value()), acceptedMimeTypes));

    // Defer the call to not block base::MessageLoop::RunTask with modal dialogs.
    QTimer::singleShot(0, [this] () {
        m_viewClient->runFileChooser(m_filePickerController);
    });
}

bool WebContentsDelegateQt::DidAddMessageToConsole(content::WebContents *source, blink::mojom::ConsoleMessageLevel log_level,
                                                   const base::string16 &message, int32_t line_no, const base::string16 &source_id)
{
    Q_UNUSED(source)
    m_viewClient->javaScriptConsoleMessage(mapToJavascriptConsoleMessageLevel(log_level), toQt(message), static_cast<int>(line_no), toQt(source_id));
    return false;
}

void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update)
{
    m_findTextHelper->handleFindReply(source, request_id, number_of_matches, selection_rect, active_match_ordinal, final_update);
}

void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *web_contents, const content::MediaStreamRequest &request,  content::MediaResponseCallback callback)
{
    MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(m_viewClient, web_contents, request, std::move(callback));
}

void WebContentsDelegateQt::SetContentsBounds(content::WebContents *source, const gfx::Rect &bounds)
{
    if (!source->HasOpener()) // is popup
        return;

    QRect frameGeometry(toQt(bounds));
    QRect geometry;
    if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView())) {
        if (rwhv->delegate() && rwhv->delegate()->window())
            geometry = frameGeometry.marginsRemoved(rwhv->delegate()->window()->frameMargins());
    }
    m_viewClient->requestGeometryChange(geometry, frameGeometry);
}

void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const GURL& url)
{
    Q_UNUSED(source)
    m_viewClient->didUpdateTargetURL(toQt(url));
}

void WebContentsDelegateQt::OnVisibilityChanged(content::Visibility visibility)
{
    if (visibility != content::Visibility::HIDDEN)
        web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetMainFrame()->GetProcess()->GetID());
}

void WebContentsDelegateQt::DidFirstVisuallyNonEmptyPaint()
{
    RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView());
    if (!rwhv)
        return;

    rwhv->OnDidFirstVisuallyNonEmptyPaint();
}

void WebContentsDelegateQt::ActivateContents(content::WebContents* contents)
{
    WebEngineSettings *settings = m_viewClient->webEngineSettings();
    if (settings->testAttribute(settings->Attribute::AllowWindowActivationFromJavaScript))
        contents->Focus();
}

void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target)
{
    Q_UNUSED(user_gesture);

    if (last_unlocked_by_target)
        web_contents->GotResponseToLockMouseRequest(true);
    else
        m_viewClient->runMouseLockPermissionRequest(toQt(web_contents->GetVisibleURL()));
}

void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *webContents, content::WebPreferences *webPreferences)
{
    m_viewClient->webEngineSettings()->overrideWebPreferences(webContents, webPreferences);
}

QWeakPointer<WebContentsAdapter> WebContentsDelegateQt::createWindow(std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture)
{
    QSharedPointer<WebContentsAdapter> newAdapter = QSharedPointer<WebContentsAdapter>::create(std::move(new_contents));

    m_viewClient->adoptNewWindow(newAdapter, static_cast<WebContentsAdapterClient::WindowOpenDisposition>(disposition), user_gesture, toQt(initial_pos), m_initialTargetUrl);

    // If the client didn't reference the adapter, it will be deleted now, and the weak pointer zeroed.
    return newAdapter;
}

void WebContentsDelegateQt::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController)
{
    m_viewClient->allowCertificateError(errorController);
}

void WebContentsDelegateQt::selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController)
{
    m_viewClient->selectClientCert(selectController);
}

void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingOrigin)
{
    m_viewClient->runGeolocationPermissionRequest(requestingOrigin);
}

void WebContentsDelegateQt::requestUserNotificationPermission(const QUrl &requestingOrigin)
{
    m_viewClient->runUserNotificationPermissionRequest(requestingOrigin);
}

extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);

void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
{
    WebEngineSettings *settings = m_viewClient->webEngineSettings();
    bool navigationAllowedByPolicy = false;
    bool navigationRequestAccepted = true;

    switch (settings->unknownUrlSchemePolicy()) {
    case WebEngineSettings::DisallowUnknownUrlSchemes:
        break;
    case WebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction:
        navigationAllowedByPolicy = has_user_gesture;
        break;
    case WebEngineSettings::AllowAllUnknownUrlSchemes:
        navigationAllowedByPolicy = true;
        break;
    default:
        Q_UNREACHABLE();
    }

    if (navigationAllowedByPolicy) {
        int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
        m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAction, is_main_frame);
        navigationRequestAccepted = navigationRequestAction == WebContentsAdapterClient::AcceptRequest;
#ifndef QT_NO_DESKTOPSERVICES
        if (navigationRequestAccepted)
            QDesktopServices::openUrl(url);
#endif
    }

    if (!navigationAllowedByPolicy || !navigationRequestAccepted) {
        QString errorDescription;
        if (!navigationAllowedByPolicy)
            errorDescription = QStringLiteral("Launching external protocol forbidden by WebEngineSettings::UnknownUrlSchemePolicy");
        else
            errorDescription = QStringLiteral("Launching external protocol suppressed by WebContentsAdapterClient::navigationRequested");
        didFailLoad(url, net::Error::ERR_ABORTED, errorDescription);
    }
}

void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool proceed, bool *proceed_to_fire_unload)
{
    Q_UNUSED(tab);
    Q_ASSERT(proceed_to_fire_unload);
    *proceed_to_fire_unload = proceed;
    if (!proceed)
        m_viewClient->windowCloseRejected();
}

void WebContentsDelegateQt::BeforeUnloadFired(bool proceed, const base::TimeTicks &proceed_time)
{
    Q_UNUSED(proceed);
    Q_UNUSED(proceed_time);
}

bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *, const GURL& security_origin, blink::mojom::MediaStreamType type)
{
    switch (type) {
    case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
        return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::AudioCapturePermission);
    case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
        return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::VideoCapturePermission);
    default:
        LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
                  << "Unsupported media stream type checked" << type;
        return false;
    }
}

void WebContentsDelegateQt::RegisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool)
{
    content::BrowserContext *context = webContents->GetBrowserContext();
    if (context->IsOffTheRecord())
        return;

    ProtocolHandler handler =
        ProtocolHandler::CreateProtocolHandler(protocol, url);

    ProtocolHandlerRegistry *registry =
        ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
    if (registry->SilentlyHandleRegisterHandlerRequest(handler))
        return;

    QWebEngineRegisterProtocolHandlerRequest request(
        QSharedPointer<RegisterProtocolHandlerRequestControllerImpl>::create(webContents, handler));
    m_viewClient->runRegisterProtocolHandlerRequest(std::move(request));
}

void WebContentsDelegateQt::UnregisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool)
{
    content::BrowserContext* context = webContents->GetBrowserContext();
    if (context->IsOffTheRecord())
        return;

    ProtocolHandler handler =
        ProtocolHandler::CreateProtocolHandler(protocol, url);

    ProtocolHandlerRegistry* registry =
        ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
    registry->RemoveHandler(handler);
}

bool WebContentsDelegateQt::TakeFocus(content::WebContents *source, bool reverse)
{
    Q_UNUSED(source);
    return m_viewClient->passOnFocus(reverse);
}

FaviconManager *WebContentsDelegateQt::faviconManager()
{
    return m_faviconManager.data();
}

FindTextHelper *WebContentsDelegateQt::findTextHelper()
{
    return m_findTextHelper.data();
}

WebEngineSettings *WebContentsDelegateQt::webEngineSettings() const {
    return m_viewClient->webEngineSettings();
}

WebContentsAdapter *WebContentsDelegateQt::webContentsAdapter() const
{
    return m_viewClient->webContentsAdapter();
}

void WebContentsDelegateQt::copyStateFrom(WebContentsDelegateQt *source)
{
    m_title = source->m_title;
    NavigationStateChanged(web_contents(), content::INVALIDATE_TYPE_URL);
    m_faviconManager->copyStateFrom(source->m_faviconManager.data());
}

WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState(content::WebContents *contents)
{
    // Based on TabLoadTracker::DetermineLoadingState

    if (contents->IsLoadingToDifferentDocument() && !contents->IsWaitingForResponse())
        return LoadingState::Loading;

    content::NavigationController &controller = contents->GetController();
    if (controller.GetLastCommittedEntry() != nullptr && !controller.IsInitialNavigation() && !controller.NeedsReload())
        return LoadingState::Loaded;

    return LoadingState::Unloaded;
}

void WebContentsDelegateQt::setLoadingState(LoadingState state)
{
    if (m_loadingState == state)
        return;

    m_loadingState = state;

    webContentsAdapter()->updateRecommendedState();
}

int &WebContentsDelegateQt::streamCount(blink::mojom::MediaStreamType type)
{
    // Based on MediaStreamCaptureIndicator::WebContentsDeviceUsage::GetStreamCount
    switch (type) {
    case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
        return m_audioStreamCount;

    case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
        return m_videoStreamCount;

    case blink::mojom::MediaStreamType::GUM_TAB_AUDIO_CAPTURE:
    case blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE:
        return m_mirroringStreamCount;

    case blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE:
    case blink::mojom::MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE:
    case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
    case blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE:
        return m_desktopStreamCount;

    case blink::mojom::MediaStreamType::NO_SERVICE:
    case blink::mojom::MediaStreamType::NUM_MEDIA_TYPES:
        NOTREACHED();
        return m_videoStreamCount;
    }
    NOTREACHED();
    return m_videoStreamCount;
}

void WebContentsDelegateQt::addDevices(const blink::MediaStreamDevices &devices)
{
    for (const auto &device : devices)
        ++streamCount(device.type);

    webContentsAdapter()->updateRecommendedState();
}

void WebContentsDelegateQt::removeDevices(const blink::MediaStreamDevices &devices)
{
    for (const auto &device : devices)
        ++streamCount(device.type);

    webContentsAdapter()->updateRecommendedState();
}

FrameFocusedObserver::FrameFocusedObserver(WebContentsAdapterClient *adapterClient)
    : m_viewClient(adapterClient)
{}

void FrameFocusedObserver::addNode(content::FrameTreeNode *node)
{
   if (m_observedNodes.contains(node))
       return;

   node->AddObserver(this);
   m_observedNodes.append(node);
}

void FrameFocusedObserver::removeNode(content::FrameTreeNode *node)
{
    node->RemoveObserver(this);
    m_observedNodes.removeOne(node);
}

void FrameFocusedObserver::OnFrameTreeNodeFocused(content::FrameTreeNode *node)
{
    Q_UNUSED(node);
    m_viewClient->updateEditActions();
}

void FrameFocusedObserver::OnFrameTreeNodeDestroyed(content::FrameTreeNode *node)
{
    m_observedNodes.removeOne(node);
    m_viewClient->updateEditActions();
}

FrameFocusedObserver::~FrameFocusedObserver()
{
    for (content::FrameTreeNode *node : m_observedNodes)
        node->RemoveObserver(this);
}

} // namespace QtWebEngineCore
