/****************************************************************************
**
** 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 (c) 2012 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 "clipboard_qt.h"
#include "clipboard_change_observer.h"
#include "type_conversion.h"

#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/clipboard_format_type.h"

#include <QGuiApplication>
#include <QImage>
#include <QMimeData>

namespace QtWebEngineCore {

static void registerMetaTypes()
{
    qRegisterMetaType<QClipboard::Mode>("QClipboard::Mode");
}

Q_CONSTRUCTOR_FUNCTION(registerMetaTypes)

Q_GLOBAL_STATIC(ClipboardChangeObserver, clipboardChangeObserver)

ClipboardChangeObserver::ClipboardChangeObserver()
{
    connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), SLOT(trackChange(QClipboard::Mode)));
}

void ClipboardChangeObserver::trackChange(QClipboard::Mode mode)
{
    ++sequenceNumber[mode];
}

} // namespace QtWebEngineCore

using namespace QtWebEngineCore;

namespace {

QScopedPointer<QMimeData> uncommittedData;
QMimeData *getUncommittedData()
{
    if (!uncommittedData)
        uncommittedData.reset(new QMimeData);
    return uncommittedData.data();
}

} // namespace

namespace ui {

// Factory function
Clipboard *Clipboard::Create()
{
    return new ClipboardQt;
}

} // namespace ui

namespace QtWebEngineCore {

void ClipboardQt::WritePortableRepresentations(ui::ClipboardBuffer type, const ObjectMap &objects)
{
    DCHECK(CalledOnValidThread());
    DCHECK(IsSupportedClipboardBuffer(type));

    for (const auto &object : objects)
        DispatchPortableRepresentation(object.first, object.second);

    // Commit the accumulated data.
    if (uncommittedData)
        QGuiApplication::clipboard()->setMimeData(uncommittedData.take(),
                                                  type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard
                                                                                          : QClipboard::Selection);

    if (type == ui::ClipboardBuffer::kCopyPaste && IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) {
        ObjectMap::const_iterator text_iter = objects.find(PortableFormat::kText);
        if (text_iter != objects.end()) {
            // Copy text and SourceTag to the selection clipboard.
            WritePortableRepresentations(ui::ClipboardBuffer::kSelection,
                                         ObjectMap(text_iter, text_iter + 1));
        }
    }
}

void ClipboardQt::WritePlatformRepresentations(ui::ClipboardBuffer buffer, std::vector<ui::Clipboard::PlatformRepresentation> platform_representations)
{
    DCHECK(CalledOnValidThread());
    DCHECK(IsSupportedClipboardBuffer(buffer));
    DispatchPlatformRepresentations(std::move(platform_representations));
}

void ClipboardQt::WriteText(const char *text_data, size_t text_len)
{
    getUncommittedData()->setText(QString::fromUtf8(text_data, text_len));
}

void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len)
{
    QString markup_string = QString::fromUtf8(markup_data, markup_len);
#if defined (Q_OS_MACOS)
    // We need to prepend the charset on macOS to prevent garbled Unicode characters
    // when pasting to certain applications (e.g. Notes, TextEdit)
    // Mirrors the behavior in ui/base/clipboard/clipboard_mac.mm in Chromium.
    markup_string.prepend(QLatin1String("<meta charset='utf-8'>"));
#endif
    getUncommittedData()->setHtml(markup_string);
}

void ClipboardQt::WriteRTF(const char *rtf_data, size_t data_len)
{
    getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), QByteArray(rtf_data, data_len));
}

void ClipboardQt::WriteWebSmartPaste()
{
    getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeWebkitSmartPaste), QByteArray());
}

void ClipboardQt::WriteBitmap(const SkBitmap &bitmap)
{
    getUncommittedData()->setImageData(toQImage(bitmap).copy());
}

void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len)
{
    // FIXME: Untested, seems to be used only for drag-n-drop.
    // Write as a mozilla url (UTF16: URL, newline, title).
    QString url = QString::fromUtf8(url_data, url_len);
    QString title = QString::fromUtf8(title_data, title_len);

    QByteArray data;
    data.append(reinterpret_cast<const char *>(url.utf16()), url.size() * 2);
    data.append('\n');
    data.append(reinterpret_cast<const char *>(title.utf16()), title.size() * 2);
    getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeMozillaURL), data);
}

void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len)
{
    getUncommittedData()->setData(QString::fromStdString(format.ToString()), QByteArray(data_data, data_len));
}

bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format, ui::ClipboardBuffer type) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    return mimeData && mimeData->hasFormat(QString::fromStdString(format.ToString()));
}

void ClipboardQt::Clear(ui::ClipboardBuffer type)
{
    QGuiApplication::clipboard()->clear(type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard
                                                                              : QClipboard::Selection);
}

void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type, std::vector<base::string16> *types,
                                     bool *contains_filenames) const
{
    if (!types || !contains_filenames) {
        NOTREACHED();
        return;
    }

    types->clear();
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (!mimeData)
        return;
    if (mimeData->hasImage() && !mimeData->formats().contains(QStringLiteral("image/png")))
        types->push_back(toString16(QStringLiteral("image/png")));
    const QStringList formats = mimeData->formats();
    for (const QString &mimeType : formats)
        types->push_back(toString16(mimeType));
    *contains_filenames = false;

    const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
    ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
}

void ClipboardQt::ReadText(ui::ClipboardBuffer type, base::string16 *result) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (mimeData)
        *result = toString16(mimeData->text());
}

void ClipboardQt::ReadAsciiText(ui::ClipboardBuffer type, std::string *result) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (mimeData)
        *result = mimeData->text().toStdString();
}

void ClipboardQt::ReadHTML(ui::ClipboardBuffer type, base::string16 *markup, std::string *src_url,
                           uint32_t *fragment_start, uint32_t *fragment_end) const
{
    markup->clear();
    if (src_url)
        src_url->clear();
    *fragment_start = 0;
    *fragment_end = 0;

    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (!mimeData)
        return;
    *markup = toString16(mimeData->html());
    *fragment_end = static_cast<uint32_t>(markup->length());
}

void ClipboardQt::ReadRTF(ui::ClipboardBuffer type, std::string *result) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (!mimeData)
        return;
    const QByteArray byteArray = mimeData->data(QString::fromLatin1(ui::kMimeTypeRTF));
    *result = std::string(byteArray.constData(), byteArray.length());
}

SkBitmap ClipboardQt::ReadImage(ui::ClipboardBuffer type) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (!mimeData)
        return SkBitmap();
    QImage image = qvariant_cast<QImage>(mimeData->imageData());

    image = image.convertToFormat(QImage::Format_ARGB32);
    SkBitmap bitmap;

    bitmap.allocN32Pixels(image.width(), image.height(), true);
    const size_t bytesPerRowDst = bitmap.rowBytes();
    const size_t bytesPerLineSrc = static_cast<size_t>(image.bytesPerLine());
    const size_t dataBytes = std::min(bytesPerRowDst, bytesPerLineSrc);
    uchar *dst = static_cast<uchar *>(bitmap.getPixels());
    const uchar *src = image.constBits();
    for (int y = 0; y < image.height(); ++y) {
        memcpy(dst, src, dataBytes);
        dst += bytesPerRowDst;
        src += bytesPerLineSrc;
    }

    return bitmap;
}

void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type, base::string16 *result) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
            clipboard_type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
    if (!mimeData)
        return;
    const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
    ui::ReadCustomDataForType(customData.constData(), customData.size(), type, result);
}

void ClipboardQt::ReadBookmark(base::string16 *title, std::string *url) const
{
    NOTIMPLEMENTED();
}

void ClipboardQt::ReadData(const ui::ClipboardFormatType &format, std::string *result) const
{
    const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData();
    if (!mimeData)
        return;
    const QByteArray byteArray = mimeData->data(QString::fromStdString(format.ToString()));
    *result = std::string(byteArray.constData(), byteArray.length());
}

uint64_t ClipboardQt::GetSequenceNumber(ui::ClipboardBuffer type) const
{
    return clipboardChangeObserver()->getSequenceNumber(type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard
                                                                                                : QClipboard::Selection);
}

} // namespace QtWebEngineCore
