/****************************************************************************
**
** 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$
**
****************************************************************************/

#include "download_manager_delegate_qt.h"

#include "base/files/file_util.h"
#include "base/time/time_to_iso8601.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/save_page_type.h"
#include "content/public/browser/web_contents.h"
#include "net/base/net_string_util.h"
#include "net/http/http_content_disposition.h"

#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QMap>
#include <QMimeDatabase>
#include <QStandardPaths>

#include "profile_adapter_client.h"
#include "profile_adapter.h"
#include "profile_qt.h"
#include "qtwebenginecoreglobal.h"
#include "type_conversion.h"
#include "web_contents_delegate_qt.h"

namespace QtWebEngineCore {

DownloadManagerDelegateQt::DownloadManagerDelegateQt(ProfileAdapter *profileAdapter)
    : m_profileAdapter(profileAdapter)
    , m_currentId(0)
    , m_weakPtrFactory(this)
    , m_nextDownloadIsUserRequested(false)
{
    Q_ASSERT(m_profileAdapter);
}

DownloadManagerDelegateQt::~DownloadManagerDelegateQt()
{
}

void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& callback)
{
    callback.Run(m_currentId);
}

download::DownloadItem *DownloadManagerDelegateQt::findDownloadById(quint32 downloadId)
{
    content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_profileAdapter->profile());
    return dlm->GetDownload(downloadId);
}

void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback)
{
    callback.Run(base::FilePath(),
                 download::DownloadItem::TARGET_DISPOSITION_PROMPT,
                 download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
                 base::FilePath(),
                 download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
}

void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
{
    if (download::DownloadItem *download = findDownloadById(downloadId))
        download->Cancel(/* user_cancel */ true);
}

void DownloadManagerDelegateQt::pauseDownload(quint32 downloadId)
{
    if (download::DownloadItem *download = findDownloadById(downloadId))
        download->Pause();
}

void DownloadManagerDelegateQt::resumeDownload(quint32 downloadId)
{
    if (download::DownloadItem *download = findDownloadById(downloadId))
        download->Resume(/* user_resume */ true);
}

void DownloadManagerDelegateQt::removeDownload(quint32 downloadId)
{
    if (download::DownloadItem *download = findDownloadById(downloadId))
        download->Remove();
}

bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* item,
                                                        const content::DownloadTargetCallback& callback)
{
    m_currentId = item->GetId();

    // Keep the forced file path if set, also as the temporary file, so the check for existence
    // will already return that the file exists. Forced file paths seem to be only used for
    // store downloads and other special downloads, so they might never end up here anyway.
    if (!item->GetForcedFilePath().empty()) {
        callback.Run(item->GetForcedFilePath(), download::DownloadItem::TARGET_DISPOSITION_PROMPT,
                     download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath(), download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
        return true;
    }

    QString suggestedFilename = toQt(item->GetSuggestedFilename());
    QString mimeTypeString = toQt(item->GetMimeType());

    int downloadType = 0;
    if (m_nextDownloadIsUserRequested) {
        downloadType = ProfileAdapterClient::UserRequested;
        m_nextDownloadIsUserRequested = false;
    } else {
        bool isAttachment = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).is_attachment();
        if (isAttachment)
            downloadType = ProfileAdapterClient::Attachment;
        else
            downloadType = ProfileAdapterClient::DownloadAttribute;
    }

    if (suggestedFilename.isEmpty())
        suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), net::kCharsetLatin1).filename());

    if (suggestedFilename.isEmpty())
        suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe());

    if (suggestedFilename.isEmpty())
        suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(item->GetURL().ExtractFileName()));

    if (suggestedFilename.isEmpty()) {
        suggestedFilename = QStringLiteral("qwe_download");
        QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString);
        if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty())
            suggestedFilename += QStringLiteral(".") + mimeType.preferredSuffix();
    }

    QDir defaultDownloadDirectory(m_profileAdapter->downloadPath());

    QString suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT());

    item->AddObserver(this);
    QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
    if (!clients.isEmpty()) {
        content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(item);
        WebContentsAdapterClient *adapterClient = nullptr;
        if (webContents)
            adapterClient = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->adapterClient();

        Q_ASSERT(m_currentId == item->GetId());
        ProfileAdapterClient::DownloadItemInfo info = {
            item->GetId(),
            toQt(item->GetURL()),
            item->GetState(),
            item->GetTotalBytes(),
            item->GetReceivedBytes(),
            mimeTypeString,
            suggestedFilePath,
            ProfileAdapterClient::UnknownSavePageFormat,
            false /* accepted */,
            false /* paused */,
            false /* done */,
            downloadType,
            item->GetLastReason(),
            adapterClient,
            suggestedFilename,
            item->GetStartTime().ToTimeT()
        };

        for (ProfileAdapterClient *client : qAsConst(clients)) {
            client->downloadRequested(info);
            if (info.accepted)
                break;
        }

        QFileInfo suggestedFile(info.path);

        if (info.accepted && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
            qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
            info.accepted = false;
        }

        if (!info.accepted) {
            cancelDownload(callback);
            return true;
        }

        base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath()));
        callback.Run(filePathForCallback,
                     download::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                     download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
                     filePathForCallback.AddExtension(toFilePathString("download")),
                     download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
    } else
        cancelDownload(callback);

    return true;
}

void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_context,
                                           base::FilePath* website_save_dir,
                                           base::FilePath* download_save_dir)
{
    static base::FilePath::StringType save_dir = toFilePathString(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
    *website_save_dir = base::FilePath(save_dir);
    *download_save_dir = base::FilePath(save_dir);
}

void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_contents,
                        const base::FilePath &suggested_path,
                        const base::FilePath::StringType &default_extension,
                        bool can_save_as_complete,
                        content::SavePackagePathPickedCallback callback)
{
    Q_UNUSED(default_extension);
    Q_UNUSED(can_save_as_complete);

    QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
    if (clients.isEmpty())
        return;

    WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
            web_contents->GetDelegate());
    const SavePageInfo &spi = contentsDelegate->savePageInfo();

    bool acceptedByDefault = false;
    QString suggestedFilePath = spi.requestedFilePath;
    if (suggestedFilePath.isEmpty()) {
        suggestedFilePath = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName()
                + QStringLiteral(".mhtml");
    } else {
        acceptedByDefault = true;
    }
    if (QFileInfo(suggestedFilePath).isRelative()) {
        const QDir downloadDir(m_profileAdapter->downloadPath());
        suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath);
    }

    ProfileAdapterClient::SavePageFormat suggestedSaveFormat
            = static_cast<ProfileAdapterClient::SavePageFormat>(spi.requestedFormat);
    if (suggestedSaveFormat == ProfileAdapterClient::UnknownSavePageFormat)
        suggestedSaveFormat = ProfileAdapterClient::MimeHtmlSaveFormat;

    // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved.
    contentsDelegate->setSavePageInfo(SavePageInfo());

    WebContentsAdapterClient *adapterClient = nullptr;
    if (web_contents)
        adapterClient = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->adapterClient();

    // Chromium doesn't increase download ID when saving page.
    ProfileAdapterClient::DownloadItemInfo info = {
        ++m_currentId,
        toQt(web_contents->GetURL()),
        download::DownloadItem::IN_PROGRESS,
        0, /* totalBytes */
        0, /* receivedBytes */
        QStringLiteral("application/x-mimearchive"),
        suggestedFilePath,
        suggestedSaveFormat,
        acceptedByDefault,
        false, /* paused */
        false, /* done */
        ProfileAdapterClient::SavePage,
        ProfileAdapterClient::NoReason,
        adapterClient,
        QFileInfo(suggestedFilePath).fileName(),
        QDateTime::currentMSecsSinceEpoch()
    };

    for (ProfileAdapterClient *client : qAsConst(clients)) {
        client->downloadRequested(info);
        if (info.accepted)
            break;
    }

    if (!info.accepted)
        return;

    std::move(callback).Run(toFilePath(info.path), static_cast<content::SavePageType>(info.savePageFormat),
                            base::Bind(&DownloadManagerDelegateQt::savePackageDownloadCreated,
                                       m_weakPtrFactory.GetWeakPtr()));
}

void DownloadManagerDelegateQt::savePackageDownloadCreated(download::DownloadItem *item)
{
    OnDownloadUpdated(item);
    item->AddObserver(this);
}

void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *download)
{
    QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
    if (!clients.isEmpty()) {
        WebContentsAdapterClient *adapterClient = nullptr;
        content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(download);
        if (webContents)
            adapterClient = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->adapterClient();

        ProfileAdapterClient::DownloadItemInfo info = {
            download->GetId(),
            toQt(download->GetURL()),
            download->GetState(),
            download->GetTotalBytes(),
            download->GetReceivedBytes(),
            toQt(download->GetMimeType()),
            QString(),
            ProfileAdapterClient::UnknownSavePageFormat,
            true /* accepted */,
            download->IsPaused(),
            download->IsDone(),
            0 /* downloadType (unused) */,
            download->GetLastReason(),
            adapterClient,
            toQt(download->GetSuggestedFilename()),
            download->GetStartTime().ToTimeT()
        };

        for (ProfileAdapterClient *client : qAsConst(clients)) {
            client->downloadUpdated(info);
        }
    }
}

void DownloadManagerDelegateQt::OnDownloadDestroyed(download::DownloadItem *download)
{
    download->RemoveObserver(this);
    download->Cancel(/* user_cancel */ false);
}

} // namespace QtWebEngineCore
