/****************************************************************************
**
** Copyright (C) 2019 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$
**
****************************************************************************/

#include "url_request_notification.h"

#include "base/supports_user_data.h"
#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
#include "profile_io_data_qt.h"
#include "qwebengineurlrequestinfo_p.h"
#include "type_conversion.h"
#include <QVariant>

namespace QtWebEngineCore {

// Calls cancel() when the URLRequest is destroyed.
class UserData : public base::SupportsUserData::Data
{
public:
    UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
    ~UserData() { m_ptr->cancel(); }
    static const char key[];

private:
    URLRequestNotification *m_ptr;
};

const char UserData::key[] = "QtWebEngineCore::URLRequestNotification";

static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
{
    return static_cast<content::ResourceType>(resourceType);
}

URLRequestNotification::URLRequestNotification(net::URLRequest *request, bool isMainFrameRequest, GURL *newUrl,
                                               QWebEngineUrlRequestInfo &&requestInfo,
                                               content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
                                               net::CompletionOnceCallback callback, QPointer<ProfileAdapter> adapter)
    : m_request(request)
    , m_isMainFrameRequest(isMainFrameRequest)
    , m_newUrl(newUrl)
    , m_originalUrl(requestInfo.requestUrl())
    , m_requestInfo(std::move(requestInfo))
    , m_webContentsGetter(webContentsGetter)
    , m_callback(std::move(callback))
    , m_profileAdapter(adapter)
{
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

    m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));

    base::PostTaskWithTraits(
        FROM_HERE,
        {content::BrowserThread::UI},
        base::BindOnce(&URLRequestNotification::notify, base::Unretained(this)));
}


void URLRequestNotification::notify()
{
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

    // May run concurrently with cancel() so no peeking at m_request here.

    int result = net::OK;
    content::WebContents *webContents = m_webContentsGetter.Run();

    if (webContents) {

        if (m_profileAdapter && m_profileAdapter->requestInterceptor()) {
            QWebEngineUrlRequestInterceptor *interceptor = m_profileAdapter->requestInterceptor();
            if (!interceptor->property("deprecated").toBool())
                interceptor->interceptRequest(m_requestInfo);
        }

        WebContentsAdapterClient *client =
            WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();

        if (!m_requestInfo.changed()) {
            client->interceptRequest(m_requestInfo);
        }

        if (m_requestInfo.changed()) {
            result = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
            // We handle the rest of the changes later when we are back in I/O thread
        }

        // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
        if (result == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
            int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
            client->navigationRequested(m_requestInfo.navigationType(),
                                        m_requestInfo.requestUrl(),
                                        navigationRequestAction,
                                        m_isMainFrameRequest);
            result = net::ERR_FAILED;
            switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
            case WebContentsAdapterClient::AcceptRequest:
                result = net::OK;
                break;
            case WebContentsAdapterClient::IgnoreRequest:
                result = net::ERR_ABORTED;
                break;
            }
            DCHECK(result != net::ERR_FAILED);
        }
    }

    // Run the callback on the IO thread.
    base::PostTaskWithTraits(
        FROM_HERE,
        {content::BrowserThread::IO},
        base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), result));
}

void URLRequestNotification::cancel()
{
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

    // May run concurrently with notify() but we only touch m_request here.

    m_request = nullptr;
}

void URLRequestNotification::complete(int error)
{
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

    if (m_request) {
        if (m_requestInfo.changed()) {
            if (m_originalUrl != m_requestInfo.d_ptr->url)
                *m_newUrl = toGurl(m_requestInfo.d_ptr->url);

            if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
                auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
                for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
                    std::string h = header.key().toStdString();
                    if (base::LowerCaseEqualsASCII(h, "referer")) {
                        m_request->SetReferrer(header.value().toStdString());
                    } else {
                        m_request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
                    }
                }
            }
        }

        if (m_request->status().status() != net::URLRequestStatus::CANCELED)
            std::move(m_callback).Run(error);
        m_request->RemoveUserData(UserData::key);
    }

    delete this;
}

}
