/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the ActiveQt framework of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qstringlist.h>
#include <qvector.h>

#include "qaxfactory.h"

#include <string.h>

#include <qt_windows.h>

QT_BEGIN_NAMESPACE

static DWORD *classRegistration = nullptr;
static DWORD dwThreadID;
static bool qAxActivity = false;
static HANDLE hEventShutdown;

#ifdef QT_DEBUG
static const DWORD dwTimeOut = 1000;
static const DWORD dwPause = 500;
#else
static const DWORD dwTimeOut = 5000; // time for EXE to be idle before shutting down
static const DWORD dwPause = 1000; // time to wait for threads to finish up
#endif

extern HANDLE qAxInstance;
extern bool qAxIsServer;
extern bool qAxOutProcServer;
extern wchar_t qAxModuleFilename[MAX_PATH];
extern QString qAxInit();
extern void qAxCleanup();
extern HRESULT UpdateRegistry(bool bRegister, bool perUser);
extern HRESULT GetClassObject(const GUID &clsid, const GUID &iid, void **ppUnk);
extern ulong qAxLockCount();
extern bool qax_winEventFilter(void *message);

STDAPI DumpIDL(const QString &outfile, const QString &ver);

// Monitors the shutdown event
static DWORD WINAPI MonitorProc(void* /* pv */)
{
    while (true) {
        WaitForSingleObject(hEventShutdown, INFINITE);
        DWORD dwWait=0;
        do {
            qAxActivity = false;
            dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
        } while (dwWait == WAIT_OBJECT_0);
        // timed out
        if (!qAxActivity && !qAxLockCount()) // if no activity let's really bail
            break;
    }
    CloseHandle(hEventShutdown);
    PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
    PostQuitMessage(0);

    return 0;
}

// Starts the monitoring thread
static bool StartMonitor()
{
    dwThreadID = GetCurrentThreadId();
    hEventShutdown = CreateEvent(nullptr, false, false, nullptr);
    if (hEventShutdown == nullptr)
        return false;
    DWORD dwThreadID;
    HANDLE h = CreateThread(nullptr, 0, MonitorProc, nullptr, 0, &dwThreadID);
    return (h != nullptr);
}

void qax_shutDown()
{
    qAxActivity = true;
    if (hEventShutdown)
        SetEvent(hEventShutdown); // tell monitor that we transitioned to zero
}

/*
    Start the COM server (if necessary).
*/
bool qax_startServer(QAxFactory::ServerType type)
{
    if (qAxIsServer)
        return true;

    const QStringList keys = qAxFactory()->featureList();
    const int keyCount = keys.count();
    if (!keyCount)
        return false;

    if (!qAxFactory()->isService())
        StartMonitor();

    classRegistration = new DWORD[keyCount];
    int object = 0;
    for (object = 0; object < keyCount; ++object) {
        IUnknown* p = nullptr;
        CLSID clsid = qAxFactory()->classID(keys.at(object));

        // Create a QClassFactory (implemented in qaxserverbase.cpp)
        HRESULT hRes = GetClassObject(clsid, IID_IClassFactory, reinterpret_cast<void **>(&p));
        if (SUCCEEDED(hRes))
            hRes = CoRegisterClassObject(clsid, p, CLSCTX_LOCAL_SERVER,
                type == QAxFactory::MultipleInstances ? REGCLS_MULTIPLEUSE : REGCLS_SINGLEUSE,
                classRegistration+object);
        if (p)
            p->Release();
    }

    qAxIsServer = true;
    return true;
}

/*
    Stop the COM server (if necessary).
*/
bool qax_stopServer()
{
    if (!qAxIsServer || !classRegistration)
        return true;

    qAxIsServer = false;

    const int keyCount = qAxFactory()->featureList().size();
    for (int object = 0; object < keyCount; ++object)
        CoRevokeClassObject(classRegistration[object]);

    delete []classRegistration;
    classRegistration = nullptr;

    Sleep(dwPause); //wait for any threads to finish

    return true;
}

QT_END_NAMESPACE

#if defined(QT_NEEDS_QMAIN)
int qMain(int, char **);
#define main qMain
#else
extern "C" int main(int, char **);
#endif

static inline QStringList commandLineArguments()
{
    QStringList result;
    int size;
    if (wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &size)) {
        result.reserve(size);
        wchar_t **argvEnd = argv + size;
        for (wchar_t **a = argv; a < argvEnd; ++a)
            result.append(QString::fromWCharArray(*a));
        LocalFree(argv);
    }
    return result;
}

static inline bool matchesOption(const QString &arg, const char *option)
{
    return (arg.startsWith(QLatin1Char('/')) || arg.startsWith(QLatin1Char('-')))
        && arg.rightRef(arg.size() - 1).compare(QLatin1String(option), Qt::CaseInsensitive) == 0;
}

namespace {
struct Arg {
    explicit Arg(const QStringList &args)
    {
        argv.reserve(args.size() + 1);
        for (const QString &a : args)
            argv.append(_strdup(a.toLocal8Bit().constData()));
        argv.append(nullptr);
    }

    ~Arg()
    {
        for (int i = 0, last = argv.size() - 1; i < last; ++i)
            free(argv.at(i));
    }

    QVector<char *> argv;
};
} // namespace

EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR, int /* nShowCmd */)
{
    QT_USE_NAMESPACE

    qAxOutProcServer = true;
    GetModuleFileName(nullptr, qAxModuleFilename, MAX_PATH);
    qAxInstance = hInstance;

    const QStringList cmds = commandLineArguments();
    QStringList unprocessed;
    unprocessed.reserve(cmds.size());

    int nRet = 0;
    bool run = true;
    bool runServer = false;
    for (int i = 0; i < cmds.count(); ++i) {
        const QString &cmd = cmds.at(i);
        if (matchesOption(cmd, "activex") || matchesOption(cmd, "embedding")) {
            runServer = true;
        } else if (matchesOption(cmd, "unregserver")) {
            nRet = UpdateRegistry(false, false);
            run = false;
            break;
        } else if (matchesOption(cmd, "regserver")) {
            nRet = UpdateRegistry(true, false);
            run = false;
            break;
        } else if (matchesOption(cmd, "unregserverperuser")) {
            nRet = UpdateRegistry(false, true);
            run = false;
            break;
        } else if (matchesOption(cmd, "regserverperuser")) {
            nRet = UpdateRegistry(true, true);
            run = false;
            break;
        } else if (matchesOption(cmd, "dumpidl")) {
            ++i;
            if (i < cmds.count()) {
                const QString &outfile = cmds.at(i);
                ++i;
                QString version;
                if (i < cmds.count() && matchesOption(cmds.at(i), "version")) {
                    ++i;
                    if (i < cmds.count())
                        version = cmds.at(i);
                    else
                        version = QStringLiteral("1.0");
                }

                nRet = DumpIDL(outfile, version);
            } else {
                qWarning("Wrong commandline syntax: <app> -dumpidl <idl file> [-version <x.y.z>]");
            }
            run = false;
            break;
        } else {
            unprocessed.append(cmds.at(i));
        }
    }

    if (run) {
        if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) {
#ifdef Q_CC_MINGW
            // define GlobalOptions class ID locally for MinGW, since it's missing from the distribution
            static const CLSID CLSID_GlobalOptions =
                { 0x0000034B, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
#endif
            // Disable C++ & SEH exception handling by the COM runtime for out-of-process COM controls.
            // Done to prevent silent crashes and enable crash dump generation.
            IGlobalOptions *globalOptions = nullptr;
            if (SUCCEEDED(CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC_SERVER,
                                           IID_IGlobalOptions, reinterpret_cast<void **>(&globalOptions)))) {
                globalOptions->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE_ANY);
                globalOptions->Release();
                globalOptions = nullptr;
            }

            {
                Arg args(unprocessed);
                qAxInit();
                if (runServer)
                    QAxFactory::startServer();
                nRet = ::main(args.argv.size() - 1, args.argv.data());
                QAxFactory::stopServer();
                qAxCleanup();
            }
            CoUninitialize();
        } else {
            qErrnoWarning("CoInitializeEx() failed.");
            nRet = -1;
        }
    }

    return nRet;
}
