/****************************************************************************
 **
 ** Copyright (C) 2016 Ivan Vizir <define-true-false@yandex.com>
 ** Copyright (C) 2016 The Qt Company Ltd.
 ** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of the QtWinExtras 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 <QtCore/qglobal.h>

#ifdef Q_CC_MINGW // MinGW: Enable SHCreateItemFromParsingName()
#  if defined(_WIN32_IE) && _WIN32_IE < 0x0700 // _WIN32_IE_IE70
#     undef _WIN32_IE
#  endif
#  ifndef _WIN32_IE
#    define _WIN32_IE 0x0700
#  endif
#endif // Q_CC_MINGW

#include "qwinjumplist.h"
#include "qwinjumplist_p.h"
#include "qwinjumplistitem.h"
#include "qwinjumplistcategory.h"
#include "qwinjumplistcategory_p.h"
#include "windowsguidsdefs_p.h"
#include "winpropkey_p.h"

#include <QtCore/qdir.h>
#include <QtCore/qdebug.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qregularexpression.h>
#include <QtCore/qt_windows.h>
#include <propvarutil.h>

#include "qwinfunctions.h"
#include "qwinfunctions_p.h"
#include "winpropkey_p.h"

#include <shobjidl.h>

QT_BEGIN_NAMESPACE

/*!
    \class QWinJumpList
    \inmodule QtWinExtras
    \brief The QWinJumpList class represents a transparent wrapper around Windows
    Jump Lists.

    \since 5.2

    An application can use Jump Lists to provide users with faster access to
    files or to display shortcuts to tasks or commands.
 */

/*!
    \title Application User Model IDs
    \externalpage http://msdn.microsoft.com/en-us/library/windows/desktop/dd378459%28v=vs.85%29.aspx
 */

// partial copy of qprocess_win.cpp:qt_create_commandline()
static QString createArguments(const QStringList &arguments)
{
    QString args;
    for (int i=0; i<arguments.size(); ++i) {
        QString tmp = arguments.at(i);
        // Quotes are escaped and their preceding backslashes are doubled.
        tmp.replace(QRegularExpression(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
        if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
            // The argument must not end with a \ since this would be interpreted
            // as escaping the quote -- rather put the \ behind the quote: e.g.
            // rather use "foo"\ than "foo\"
            int i = tmp.length();
            while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\'))
                --i;
            tmp.insert(i, QLatin1Char('"'));
            tmp.prepend(QLatin1Char('"'));
        }
        args += QLatin1Char(' ') + tmp;
    }
    return args;
}

void QWinJumpListPrivate::warning(const char *function, HRESULT hresult)
{
    const QString err = QtWin::errorStringFromHresult(hresult);
    qWarning("QWinJumpList: %s() failed: %#010x, %s.", function, unsigned(hresult), qPrintable(err));
}

QString QWinJumpListPrivate::iconsDirPath()
{
    QString iconDirPath = QDir::tempPath() + QLatin1Char('/')
        + QCoreApplication::applicationName() + QLatin1String("/qt-jl-icons/");
    QDir().mkpath(iconDirPath);
    return iconDirPath;
}

void QWinJumpListPrivate::invalidate()
{
    Q_Q(QWinJumpList);
    if (!pDestList)
        return;

    if (!dirty) {
        dirty = true;
        QMetaObject::invokeMethod(q, "_q_rebuild", Qt::QueuedConnection);
    }
}

void QWinJumpListPrivate::_q_rebuild()
{
    if (beginList()) {
        if (recent && recent->isVisible())
            appendKnownCategory(KDC_RECENT);
        if (frequent && frequent->isVisible())
            appendKnownCategory(KDC_FREQUENT);
        for (QWinJumpListCategory *category : qAsConst(categories)) {
            if (category->isVisible())
                appendCustomCategory(category);
        }
        if (tasks && tasks->isVisible())
            appendTasks(tasks->items());
        commitList();
    }
    dirty = false;
}

void QWinJumpListPrivate::destroy()
{
    delete recent;
    recent = nullptr;
    delete frequent;
    frequent = nullptr;
    delete tasks;
    tasks = nullptr;
    qDeleteAll(categories);
    categories.clear();
    invalidate();
}

bool QWinJumpListPrivate::beginList()
{
    HRESULT hresult = S_OK;
    if (!identifier.isEmpty()) {
        wchar_t *id = qt_qstringToNullTerminated(identifier);
        hresult = pDestList->SetAppID(id);
        delete[] id;
    }
    if (SUCCEEDED(hresult)) {
        UINT maxSlots = 0;
        IUnknown *array = nullptr;
        hresult = pDestList->BeginList(&maxSlots, qIID_IUnknown, reinterpret_cast<void **>(&array));
        if (array)
            array->Release();
    }
    if (FAILED(hresult))
        QWinJumpListPrivate::warning("BeginList", hresult);
    return SUCCEEDED(hresult);
}

bool QWinJumpListPrivate::commitList()
{
    HRESULT hresult = pDestList->CommitList();
    if (FAILED(hresult))
        QWinJumpListPrivate::warning("CommitList", hresult);
    return SUCCEEDED(hresult);
}

void QWinJumpListPrivate::appendKnownCategory(KNOWNDESTCATEGORY category)
{
    HRESULT hresult = pDestList->AppendKnownCategory(category);
    if (FAILED(hresult))
        QWinJumpListPrivate::warning("AppendKnownCategory", hresult);
}

void QWinJumpListPrivate::appendCustomCategory(QWinJumpListCategory *category)
{
    IObjectCollection *collection = toComCollection(category->items());
    if (collection) {
        wchar_t *title = qt_qstringToNullTerminated(category->title());
        HRESULT hresult = pDestList->AppendCategory(title, collection);
        if (FAILED(hresult))
            QWinJumpListPrivate::warning("AppendCategory", hresult);
        delete[] title;
        collection->Release();
    }
}

void QWinJumpListPrivate::appendTasks(const QList<QWinJumpListItem *> &items)
{
    IObjectCollection *collection = toComCollection(items);
    if (collection) {
        HRESULT hresult = pDestList->AddUserTasks(collection);
        if (FAILED(hresult))
            QWinJumpListPrivate::warning("AddUserTasks", hresult);
        collection->Release();
    }
}

QList<QWinJumpListItem *> QWinJumpListPrivate::fromComCollection(IObjectArray *array)
{
    QList<QWinJumpListItem *> list;
    UINT count = 0;
    array->GetCount(&count);
    for (UINT i = 0; i < count; ++i) {
        IUnknown *collectionItem = nullptr;
        HRESULT hresult = array->GetAt(i, qIID_IUnknown, reinterpret_cast<void **>(&collectionItem));
        if (FAILED(hresult)) {
            QWinJumpListPrivate::warning("GetAt", hresult);
            continue;
        }
        IShellItem2 *shellItem = nullptr;
        IShellLinkW *shellLink = nullptr;
        QWinJumpListItem *jumplistItem = nullptr;
        if (SUCCEEDED(collectionItem->QueryInterface(qIID_IShellItem2, reinterpret_cast<void **>(&shellItem)))) {
            jumplistItem = fromIShellItem(shellItem);
            shellItem->Release();
        } else if (SUCCEEDED(collectionItem->QueryInterface(qIID_IShellLinkW, reinterpret_cast<void **>(&shellLink)))) {
            jumplistItem = fromIShellLink(shellLink);
            shellLink->Release();
        } else {
            qWarning("QWinJumpList: object of unexpected class found");
        }
        collectionItem->Release();
        if (jumplistItem)
            list.append(jumplistItem);
    }
    return list;
}

IObjectCollection *QWinJumpListPrivate::toComCollection(const QList<QWinJumpListItem *> &list)
{
    if (list.isEmpty())
        return nullptr;
    IObjectCollection *collection = nullptr;
    HRESULT hresult = CoCreateInstance(qCLSID_EnumerableObjectCollection, nullptr, CLSCTX_INPROC_SERVER, qIID_IObjectCollection, reinterpret_cast<void **>(&collection));
    if (FAILED(hresult)) {
        QWinJumpListPrivate::warning("QWinJumpList: failed to instantiate IObjectCollection", hresult);
        return nullptr;
    }
    for (QWinJumpListItem *item : list) {
        IUnknown *iitem = toICustomDestinationListItem(item);
        if (iitem) {
            collection->AddObject(iitem);
            iitem->Release();
        }
    }
    return collection;
}

QWinJumpListItem *QWinJumpListPrivate::fromIShellLink(IShellLinkW *link)
{
    auto *item = new QWinJumpListItem(QWinJumpListItem::Link);

    IPropertyStore *linkProps;
    link->QueryInterface(qIID_IPropertyStore, reinterpret_cast<void **>(&linkProps));
    PROPVARIANT var;
    linkProps->GetValue(qPKEY_Link_Arguments, &var);
    item->setArguments(QStringList(QString::fromWCharArray(var.pwszVal)));
    PropVariantClear(&var);
    linkProps->Release();

    const int buffersize = 2048;
    wchar_t buffer[buffersize];

    link->GetDescription(buffer, INFOTIPSIZE);
    item->setDescription(QString::fromWCharArray(buffer));

    int dummyindex;
    link->GetIconLocation(buffer, buffersize-1, &dummyindex);
    item->setIcon(QIcon(QString::fromWCharArray(buffer)));

    link->GetPath(buffer, buffersize-1, 0, 0);
    item->setFilePath(QDir::fromNativeSeparators(QString::fromWCharArray(buffer)));

    return item;
}

QWinJumpListItem *QWinJumpListPrivate::fromIShellItem(IShellItem2 *shellitem)
{
    auto *item = new QWinJumpListItem(QWinJumpListItem::Destination);
    wchar_t *strPtr;
    shellitem->GetDisplayName(SIGDN_FILESYSPATH, &strPtr);
    item->setFilePath(QDir::fromNativeSeparators(QString::fromWCharArray(strPtr)));
    CoTaskMemFree(strPtr);
    return item;
}

IUnknown *QWinJumpListPrivate::toICustomDestinationListItem(const QWinJumpListItem *item)
{
    switch (item->type()) {
    case QWinJumpListItem::Destination :
        return toIShellItem(item);
    case QWinJumpListItem::Link :
        return toIShellLink(item);
    case QWinJumpListItem::Separator :
        return makeSeparatorShellItem();
    default:
        return nullptr;
    }
}

IShellLinkW *QWinJumpListPrivate::toIShellLink(const QWinJumpListItem *item)
{
    IShellLinkW *link = nullptr;
    HRESULT hresult = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, qIID_IShellLinkW, reinterpret_cast<void **>(&link));
    if (FAILED(hresult)) {
        QWinJumpListPrivate::warning("QWinJumpList: failed to instantiate IShellLinkW", hresult);
        return nullptr;
    }

    const QString args = createArguments(item->arguments());
    const int iconPathSize = QWinJumpListPrivate::iconsDirPath().size()
        + int(sizeof(void *)) * 2 + 4; // path + ptr-name-in-hex + .ico
    const int bufferSize = qMax(args.size(),
                                qMax(item->workingDirectory().size(),
                                     qMax(item->description().size(),
                                          qMax(item->title().size(),
                                               qMax(item->filePath().size(), iconPathSize))))) + 1;
    auto *buffer = new wchar_t[bufferSize];

    if (!item->description().isEmpty()) {
        qt_qstringToNullTerminated(item->description(), buffer);
        link->SetDescription(buffer);
    }

    qt_qstringToNullTerminated(item->filePath(), buffer);
    link->SetPath(buffer);

    if (!item->workingDirectory().isEmpty()) {
        qt_qstringToNullTerminated(item->workingDirectory(), buffer);
        link->SetWorkingDirectory(buffer);
    }

    qt_qstringToNullTerminated(args, buffer);
    link->SetArguments(buffer);

    if (!item->icon().isNull()) {
        QString iconPath = QWinJumpListPrivate::iconsDirPath() + QString::number(reinterpret_cast<quintptr>(item), 16) + QLatin1String(".ico");
        bool iconSaved = item->icon().pixmap(GetSystemMetrics(SM_CXICON)).save(iconPath, "ico");
        if (iconSaved) {
            qt_qstringToNullTerminated(iconPath, buffer);
            link->SetIconLocation(buffer, 0);
        }
    }

    IPropertyStore *properties;
    PROPVARIANT titlepv;
    hresult = link->QueryInterface(qIID_IPropertyStore, reinterpret_cast<void **>(&properties));
    if (FAILED(hresult)) {
        link->Release();
        return nullptr;
    }

    qt_qstringToNullTerminated(item->title(), buffer);
    InitPropVariantFromString(buffer, &titlepv);
    properties->SetValue(qPKEY_Title, titlepv);
    properties->Commit();
    properties->Release();
    PropVariantClear(&titlepv);

    delete[] buffer;
    return link;
}

IShellItem2 *QWinJumpListPrivate::toIShellItem(const QWinJumpListItem *item)
{
    IShellItem2 *shellitem = nullptr;
    QScopedArrayPointer<wchar_t> buffer(qt_qstringToNullTerminated(item->filePath()));
    SHCreateItemFromParsingName(buffer.data(), nullptr, qIID_IShellItem2, reinterpret_cast<void **>(&shellitem));
    return shellitem;
}

IShellLinkW *QWinJumpListPrivate::makeSeparatorShellItem()
{
    IShellLinkW *separator;
    HRESULT res = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, qIID_IShellLinkW, reinterpret_cast<void **>(&separator));
    if (FAILED(res))
        return nullptr;

    IPropertyStore *properties;
    res = separator->QueryInterface(qIID_IPropertyStore, reinterpret_cast<void **>(&properties));
    if (FAILED(res)) {
        separator->Release();
        return nullptr;
    }

    PROPVARIANT isSeparator;
    InitPropVariantFromBoolean(TRUE, &isSeparator);
    properties->SetValue(qPKEY_AppUserModel_IsDestListSeparator, isSeparator);
    properties->Commit();
    properties->Release();
    PropVariantClear(&isSeparator);

    return separator;
}

/*!
    Constructs a QWinJumpList with the parent object \a parent.
 */
QWinJumpList::QWinJumpList(QObject *parent) :
    QObject(parent), d_ptr(new QWinJumpListPrivate)
{
    Q_D(QWinJumpList);
    d->q_ptr = this;
    HRESULT hresult = CoCreateInstance(qCLSID_DestinationList, nullptr, CLSCTX_INPROC_SERVER, qIID_ICustomDestinationList, reinterpret_cast<void **>(&d_ptr->pDestList));
    if (FAILED(hresult))
        QWinJumpListPrivate::warning("CoCreateInstance", hresult);
    d->invalidate();
}

/*!
    Destroys the QWinJumpList.
 */
QWinJumpList::~QWinJumpList()
{
    Q_D(QWinJumpList);
    if (d->dirty)
        d->_q_rebuild();
    if (d->pDestList) {
        d->pDestList->Release();
        d->pDestList = nullptr;
    }
    d->destroy();
}

/*!
    \property QWinJumpList::identifier
    \brief the jump list identifier

    Specifies an optional explicit unique identifier for the
    application jump list.

    The default value is empty; a system-defined internal identifier
    is used instead. See \l {Application User Model IDs} on MSDN for
    further details.

    \note The identifier cannot have more than \c 128 characters and
    cannot contain spaces. A too long identifier is automatically truncated
    to \c 128 characters, and spaces are replaced by underscores.
 */
QString QWinJumpList::identifier() const
{
    Q_D(const QWinJumpList);
    return d->identifier;
}

void QWinJumpList::setIdentifier(const QString &identifier)
{
    Q_D(QWinJumpList);
    QString id = identifier;
    id.replace(QLatin1Char(' '), QLatin1Char('_'));
    if (id.size() > 128)
        id.truncate(128);
    if (d->identifier != id) {
        d->identifier = id;
        d->invalidate();
    }
}

/*!
    Returns the recent items category in the jump list.
 */
QWinJumpListCategory *QWinJumpList::recent() const
{
    Q_D(const QWinJumpList);
    if (!d->recent) {
        auto *that = const_cast<QWinJumpList *>(this);
        that->d_func()->recent = QWinJumpListCategoryPrivate::create(QWinJumpListCategory::Recent, that);
    }
    return d->recent;
}

/*!
    Returns the frequent items category in the jump list.
 */
QWinJumpListCategory *QWinJumpList::frequent() const
{
    Q_D(const QWinJumpList);
    if (!d->frequent) {
        auto *that = const_cast<QWinJumpList *>(this);
        that->d_func()->frequent = QWinJumpListCategoryPrivate::create(QWinJumpListCategory::Frequent, that);
    }
    return d->frequent;
}

/*!
    Returns the tasks category in the jump list.
 */
QWinJumpListCategory *QWinJumpList::tasks() const
{
    Q_D(const QWinJumpList);
    if (!d->tasks) {
        auto *that = const_cast<QWinJumpList *>(this);
        that->d_func()->tasks = QWinJumpListCategoryPrivate::create(QWinJumpListCategory::Tasks, that);
    }
    return d->tasks;
}

/*!
    Returns the custom categories in the jump list.
 */
QList<QWinJumpListCategory *> QWinJumpList::categories() const
{
    Q_D(const QWinJumpList);
    return d->categories;
}

/*!
    Adds a custom \a category to the jump list.
 */
void QWinJumpList::addCategory(QWinJumpListCategory *category)
{
    Q_D(QWinJumpList);
    if (!category)
        return;

    QWinJumpListCategoryPrivate::get(category)->jumpList = this;
    d->categories.append(category);
    d->invalidate();
}

/*!
    \overload addCategory()
    Creates a custom category with provided \a title and optional \a items,
    and adds it to the jump list.
 */
QWinJumpListCategory *QWinJumpList::addCategory(const QString &title, const QList<QWinJumpListItem *> items)
{
    auto *category = new QWinJumpListCategory(title);
    for (QWinJumpListItem *item : items)
        category->addItem(item);
    addCategory(category);
    return category;
}

/*!
    Clears the jump list.

    \sa QWinJumpListCategory::clear()
 */
void QWinJumpList::clear()
{
    Q_D(QWinJumpList);
    recent()->clear();
    frequent()->clear();
    if (d->tasks)
        d->tasks->clear();
    for (QWinJumpListCategory *category : qAsConst(d->categories))
        category->clear();
    d->destroy();
}

#ifndef QT_NO_DEBUG_STREAM

QDebug operator<<(QDebug debug, const QWinJumpList *jumplist)
{
    QDebugStateSaver saver(debug);
    debug.nospace();
    debug.noquote();
    debug << "QWinJumpList(";
    if (jumplist) {
        debug << "(identifier=\"" << jumplist->identifier() << "\", recent="
            << jumplist->recent() << ", frequent=" << jumplist->frequent()
            << ", tasks=" << jumplist->tasks()
            << ", categories=" << jumplist->categories();
    } else {
        debug << '0';
    }
    debug << ')';
    return debug;
}
#endif // !QT_NO_DEBUG_STREAM

QT_END_NAMESPACE

#include "moc_qwinjumplist.cpp"
