/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications 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 "appxphoneengine.h"
#include "appxengine_p.h"

#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QHash>
#include <QtCore/QUuid>
#include <QtCore/QLoggingCategory>
#include <QtCore/QDateTime>

#include <comdef.h>
#include <psapi.h>

#include <ShlObj.h>
#include <Shlwapi.h>
#include <wsdevlicensing.h>
#include <AppxPackaging.h>
#include <xmllite.h>
#include <wrl.h>
#include <windows.applicationmodel.h>
#include <windows.management.deployment.h>

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Management::Deployment;
using namespace ABI::Windows::ApplicationModel;
using namespace ABI::Windows::System;

// From Microsoft.Phone.Tools.Deploy assembly
namespace PhoneTools {
    enum DeploymentOptions
    {
        None = 0,
        PA = 1,
        Debug = 2,
        Infused = 4,
        Lightup = 8,
        Enterprise = 16,
        Sideload = 32,
        TypeMask = 255,
        UninstallDisabled = 256,
        SkipUpdateAppInForeground = 512,
        DeleteXap = 1024,
        InstallOnSD = 65536,
        OptOutSD = 131072
    };
    enum PackageType
    {
        UnknownAppx = 0,
        Main = 1,
        Framework = 2,
        Resource = 4,
        Bundle = 8,
        Xap = 0
    };
}

QT_USE_NAMESPACE

#include <corecon.h>
#include <ccapi_12.h>
Q_GLOBAL_STATIC_WITH_ARGS(CoreConServer, coreConServer, (12))

#undef RETURN_IF_FAILED
#define RETURN_IF_FAILED(msg, ret) \
    if (FAILED(hr)) { \
        qCWarning(lcWinRtRunner).nospace() << msg << ": 0x" << QByteArray::number(hr, 16).constData() \
                                           << ' ' << coreConServer->formatError(hr); \
        ret; \
    }

// Set a break handler for gracefully breaking long-running ops
static bool g_ctrlReceived = false;
static bool g_handleCtrl = false;
static BOOL WINAPI ctrlHandler(DWORD type)
{
    switch (type) {
    case CTRL_C_EVENT:
    case CTRL_CLOSE_EVENT:
    case CTRL_LOGOFF_EVENT:
        g_ctrlReceived = g_handleCtrl;
        return g_handleCtrl;
    case CTRL_BREAK_EVENT:
    case CTRL_SHUTDOWN_EVENT:
    default:
        break;
    }
    return false;
}

class AppxPhoneEnginePrivate : public AppxEnginePrivate
{
public:
    QString productId;

    ComPtr<ICcConnection> connection;
    CoreConDevice *device;
    QSet<QString> dependencies;
};

static ProcessorArchitecture toProcessorArchitecture(APPX_PACKAGE_ARCHITECTURE appxArch)
{
    switch (appxArch) {
    case APPX_PACKAGE_ARCHITECTURE_X86:
        return ProcessorArchitecture_X86;
    case APPX_PACKAGE_ARCHITECTURE_ARM:
        return ProcessorArchitecture_Arm;
    case APPX_PACKAGE_ARCHITECTURE_X64:
        return ProcessorArchitecture_X64;
    case APPX_PACKAGE_ARCHITECTURE_NEUTRAL:
        // fall-through intended
    default:
        return ProcessorArchitecture_Neutral;
    }
}

static bool getPhoneProductId(IStream *manifestStream, QString *productId)
{
    // Read out the phone product ID (not supported by AppxManifestReader)
    ComPtr<IXmlReader> xmlReader;
    HRESULT hr = CreateXmlReader(IID_PPV_ARGS(&xmlReader), NULL);
    RETURN_FALSE_IF_FAILED("Failed to create XML reader");

    hr = xmlReader->SetInput(manifestStream);
    RETURN_FALSE_IF_FAILED("Failed to set manifest as input");

    while (!xmlReader->IsEOF()) {
        XmlNodeType nodeType;
        hr = xmlReader->Read(&nodeType);
        RETURN_FALSE_IF_FAILED("Failed to read next node in manifest");
        if (nodeType == XmlNodeType_Element) {
            PCWSTR uri;
            hr = xmlReader->GetNamespaceUri(&uri, NULL);
            RETURN_FALSE_IF_FAILED("Failed to read namespace URI of current node");
            if (wcscmp(uri, L"http://schemas.microsoft.com/appx/2014/phone/manifest") == 0) {
                PCWSTR localName;
                hr = xmlReader->GetLocalName(&localName, NULL);
                RETURN_FALSE_IF_FAILED("Failed to get local name of current node");
                if (wcscmp(localName, L"PhoneIdentity") == 0) {
                    hr = xmlReader->MoveToAttributeByName(L"PhoneProductId", NULL);
                    if (hr == S_FALSE)
                        continue;
                    RETURN_FALSE_IF_FAILED("Failed to seek to the PhoneProductId attribute");
                    PCWSTR phoneProductId;
                    UINT length;
                    hr = xmlReader->GetValue(&phoneProductId, &length);
                    RETURN_FALSE_IF_FAILED("Failed to read the value of the PhoneProductId attribute");
                    *productId = QLatin1Char('{') + QString::fromWCharArray(phoneProductId, length) + QLatin1Char('}');
                    return true;
                }
            }
        }
    }
    return false;
}

bool AppxPhoneEngine::canHandle(Runner *runner)
{
    return getManifestFile(runner->app());
}

RunnerEngine *AppxPhoneEngine::create(Runner *runner)
{
    QScopedPointer<AppxPhoneEngine> engine(new AppxPhoneEngine(runner));
    if (engine->d_ptr->hasFatalError)
        return 0;

    return engine.take();
}

QStringList AppxPhoneEngine::deviceNames()
{
    QStringList deviceNames;

    const QList<CoreConDevice *> devices = coreConServer->devices();
    for (const CoreConDevice *device : devices)
        deviceNames.append(device->name());
    return deviceNames;
}

AppxPhoneEngine::AppxPhoneEngine(Runner *runner)
    : AppxEngine(runner, new AppxPhoneEnginePrivate)
{
    Q_D(AppxPhoneEngine);
    if (d->hasFatalError)
        return;
    d->hasFatalError = true;

    ComPtr<IStream> manifestStream;
    HRESULT hr;
    if (d->manifestReader) {
        hr = d->manifestReader->GetStream(&manifestStream);
        RETURN_VOID_IF_FAILED("Failed to query manifest stream from manifest reader.");
    } else {
        hr = SHCreateStreamOnFile(wchar(d->manifest), STGM_READ, &manifestStream);
        RETURN_VOID_IF_FAILED("Failed to open manifest stream");
    }

    if (!getPhoneProductId(manifestStream.Get(), &d->productId)) {
        qCWarning(lcWinRtRunner) << "Failed to read phone product ID from the manifest.";
        return;
    }

    if (!coreConServer->initialize()) {
        while (!coreConServer.exists())
            Sleep(1);
    }

    // Get the device
    d->device = coreConServer->devices().value(d->runner->deviceIndex());
    if (!d->device || !d->device->handle()) {
        d->hasFatalError = true;
        qCWarning(lcWinRtRunner) << "Invalid device specified:" << d->runner->deviceIndex();
        return;
    }



    // Set a break handler for gracefully exiting from long-running operations
    SetConsoleCtrlHandler(&ctrlHandler, true);
    d->hasFatalError = false;
}

AppxPhoneEngine::~AppxPhoneEngine()
{
}

QString AppxPhoneEngine::extensionSdkPath() const
{
    const QByteArray extensionSdkDirRaw = qgetenv("ExtensionSdkDir");
    if (extensionSdkDirRaw.isEmpty()) {
        qCWarning(lcWinRtRunner) << "The environment variable ExtensionSdkDir is not set.";
        return QString();
    }
    return QString::fromLocal8Bit(extensionSdkDirRaw);
}

bool AppxPhoneEngine::installPackage(IAppxManifestReader *reader, const QString &filePath)
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__ << filePath;

    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to obtain connection object");

    ComPtr<IStream> manifestStream;
    hr = reader->GetStream(&manifestStream);
    RETURN_FALSE_IF_FAILED("Failed to get manifest stream from reader");

    QString productIdString;
    if (!getPhoneProductId(manifestStream.Get(), &productIdString)) {
        qCWarning(lcWinRtRunner) << "Failed to get phone product ID from manifest reader.";
        return false;
    }
    _bstr_t productId(wchar(productIdString));

    VARIANT_BOOL isInstalled;
    hr = connection->IsApplicationInstalled(productId, &isInstalled);
    RETURN_FALSE_IF_FAILED("Failed to determine if package is installed");
    if (isInstalled) {
        qCDebug(lcWinRtRunner) << "Package" << productIdString << "is already installed";
        return true;
    }

    ComPtr<IAppxManifestProperties> properties;
    hr = reader->GetProperties(&properties);
    RETURN_FALSE_IF_FAILED("Failed to get manifest properties");

    BOOL isFramework;
    hr = properties->GetBoolValue(L"Framework", &isFramework);
    RETURN_FALSE_IF_FAILED("Failed to determine whether package is a framework");

    const QString deploymentFlags = QString::number(isFramework ? PhoneTools::None : PhoneTools::Sideload);
    _bstr_t deploymentFlagsAsGenre(wchar(deploymentFlags));
    const QString packageType = QString::number(isFramework ? PhoneTools::Framework : PhoneTools::Main);
    _bstr_t packageTypeAsIconPath(wchar(packageType));
    _bstr_t packagePath(wchar(QDir::toNativeSeparators(filePath)));
    hr = connection->InstallApplication(productId, productId, deploymentFlagsAsGenre,
                                        packageTypeAsIconPath, packagePath);
    if (hr == 0x80073d06) { // No public E_* macro available
        qCWarning(lcWinRtRunner) << "Found a newer version of " << filePath
                                 << " on the target device, skipping...";
    } else {
        RETURN_FALSE_IF_FAILED("Failed to install the package");
    }

    return true;
}

bool AppxPhoneEngine::connect()
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    HRESULT hr;
    if (!d->connection) {
        _bstr_t connectionName;
        hr = static_cast<ICcServer *>(coreConServer->handle())->GetConnection(
                    static_cast<ICcDevice *>(d->device->handle()), 5000, NULL, connectionName.GetAddress(), &d->connection);
        RETURN_FALSE_IF_FAILED("Failed to connect to device");
    }

    VARIANT_BOOL connected;
    hr = d->connection->IsConnected(&connected);
    RETURN_FALSE_IF_FAILED("Failed to determine connection state");
    if (connected)
        return true;

    hr = d->connection->ConnectDevice();
    RETURN_FALSE_IF_FAILED("Failed to connect to device");

    return true;
}

bool AppxPhoneEngine::install(bool removeFirst)
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    if (!connect())
        return false;

    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to obtain connection object");

    _bstr_t productId(wchar(d->productId));
    VARIANT_BOOL isInstalled;
    hr = connection->IsApplicationInstalled(productId, &isInstalled);
    RETURN_FALSE_IF_FAILED("Failed to obtain the installation status");
    if (isInstalled) {
        if (!removeFirst)
            return true;
        if (!remove())
            return false;
    }

    if (!installDependencies())
        return false;

    const QDir base = QFileInfo(d->executable).absoluteDir();
    const bool existingPackage = d->runner->app().endsWith(QLatin1String(".appx"));
    const QString packageFileName = existingPackage
                                      ? d->runner->app()
                                      : base.absoluteFilePath(d->packageFamilyName + QStringLiteral(".appx"));
    if (!existingPackage) {
        if (!createPackage(packageFileName))
            return false;

        if (!sign(packageFileName))
            return false;
    } else {
        qCDebug(lcWinRtRunner) << "Installing existing package.";
    }

    return installPackage(d->manifestReader.Get(), packageFileName);
}

bool AppxPhoneEngine::remove()
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    if (!connect())
        return false;

    if (!d->connection)
        return false;

    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to obtain connection object");

    _bstr_t app = wchar(d->productId);
    hr = connection->UninstallApplication(app);
    RETURN_FALSE_IF_FAILED("Failed to uninstall the package");

    return true;
}

bool AppxPhoneEngine::start()
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    if (!connect())
        return false;

    if (!d->runner->arguments().isEmpty())
        qCWarning(lcWinRtRunner) << "Arguments are not currently supported for Windows Phone Appx packages.";

    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to cast connection object");

    _bstr_t productId(wchar(d->productId));
    DWORD pid;
    hr = connection->LaunchApplication(productId, &pid);
    RETURN_FALSE_IF_FAILED("Failed to start the package");

    d->pid = pid;
    return true;
}

bool AppxPhoneEngine::enableDebugging(const QString &debuggerExecutable, const QString &debuggerArguments)
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    Q_UNUSED(debuggerExecutable);
    Q_UNUSED(debuggerArguments);
    return false;
}

bool AppxPhoneEngine::disableDebugging()
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    return false;
}

bool AppxPhoneEngine::setLoopbackExemptClientEnabled(bool)
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    return false;
}

bool AppxPhoneEngine::setLoopbackExemptServerEnabled(bool)
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    return false;
}

bool AppxPhoneEngine::setLoggingRules(const QByteArray &)
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    return false;
}

bool AppxPhoneEngine::suspend()
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;
    return false;
}

bool AppxPhoneEngine::waitForFinished(int secs)
{
    Q_D(AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to cast connection");

    g_handleCtrl = true;
    int time = 0;
    forever {
        ++time;
        if ((secs && time > secs) || g_ctrlReceived) {
            g_handleCtrl = false;
            return false;
        }

        Sleep(1000); // Wait one second between checks
        qCDebug(lcWinRtRunner) << "Waiting for app to quit - msecs to go: " << secs - time;
    }
    g_handleCtrl = false;
    return true;
}

bool AppxPhoneEngine::stop()
{
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    if (!connect())
        return false;

#if 0 // This does not actually stop the app - QTBUG-41946
    Q_D(AppxPhoneEngine);
    ComPtr<ICcConnection3> connection;
    HRESULT hr = d->connection.As(&connection);
    RETURN_FALSE_IF_FAILED("Failed to cast connection object");

    _bstr_t productId(wchar(d->productId));
    hr = connection->TerminateRunningApplicationInstances(productId);
    RETURN_FALSE_IF_FAILED("Failed to stop the package");

    return true;
#else
    return remove();
#endif
}

QString AppxPhoneEngine::devicePath(const QString &relativePath) const
{
    Q_D(const AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    return QStringLiteral("%FOLDERID_APPID_ISOROOT%\\") + d->productId
            + QStringLiteral("\\%LOCL%\\") + relativePath;
}

bool AppxPhoneEngine::sendFile(const QString &localFile, const QString &deviceFile)
{
    Q_D(const AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    HRESULT hr = d->connection->SendFile(_bstr_t(wchar(localFile)), _bstr_t(wchar(deviceFile)),
                                         CREATE_ALWAYS, NULL);
    RETURN_FALSE_IF_FAILED("Failed to send the file");

    return true;
}

bool AppxPhoneEngine::receiveFile(const QString &deviceFile, const QString &localFile)
{
    Q_D(const AppxPhoneEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    HRESULT hr = d->connection->ReceiveFile(_bstr_t(wchar(deviceFile)),
                                            _bstr_t(wchar(localFile)), uint(2));
    RETURN_FALSE_IF_FAILED("Failed to receive the file");

    return true;
}
