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

#ifndef QAXFACTORY_H
#define QAXFACTORY_H

#include <QtCore/qcompilerdetection.h>

QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Woverloaded-virtual") // gcc complains about QObject::metaObject() being hidden.
QT_WARNING_DISABLE_CLANG("-Woverloaded-virtual") // clang-cl complains about QObject::metaObject() being hidden.

#include <QtCore/qhash.h>
#include <QtCore/quuid.h>
#include <QtCore/qfactoryinterface.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qsettings.h>

struct IUnknown;
struct IDispatch;

QT_BEGIN_NAMESPACE

class QWidget;
class QSettings;

class QAxFactory : public QObject
{
    Q_DISABLE_COPY_MOVE(QAxFactory)
public:
    QAxFactory(const QUuid &libId, const QUuid &appId);
    ~QAxFactory() override;

    virtual QStringList featureList() const = 0;

    virtual QObject *createObject(const QString &key) = 0;
    virtual const QMetaObject *metaObject(const QString &key) const = 0;
    virtual bool createObjectWrapper(QObject *object, IDispatch **wrapper);

    virtual QUuid classID(const QString &key) const;
    virtual QUuid interfaceID(const QString &key) const;
    virtual QUuid eventsID(const QString &key) const;

    virtual QUuid typeLibID() const;
    virtual QUuid appID() const;

    virtual void registerClass(const QString &key, QSettings *) const;
    virtual void unregisterClass(const QString &key, QSettings *) const;

    virtual bool validateLicenseKey(const QString &key, const QString &licenseKey) const;

    virtual QString exposeToSuperClass(const QString &key) const;
    virtual bool stayTopLevel(const QString &key) const;
    virtual bool hasStockEvents(const QString &key) const;
    virtual bool isService() const;

    enum ServerType {
        SingleInstance,
        MultipleInstances
    };

    static bool isServer();
    static QString serverDirPath();
    static QString serverFilePath();
    static bool startServer(ServerType type = MultipleInstances);
    static bool stopServer();

    static bool registerActiveObject(QObject *object);

private:
    QUuid typelib;
    QUuid app;
};

extern QAxFactory *qAxFactory();

extern bool qax_startServer(QAxFactory::ServerType);

inline bool QAxFactory::startServer(ServerType type)
{
    // implementation in qaxservermain.cpp
    return qax_startServer(type);
}

extern bool qax_stopServer();

inline bool QAxFactory::stopServer()
{
    // implementation in qaxservermain.cpp
    return qax_stopServer();
}

#define QAXFACTORY_EXPORT(IMPL, TYPELIB, APPID) \
    QT_BEGIN_NAMESPACE \
    QAxFactory *qax_instantiate()               \
    {                                                   \
        IMPL *impl = new IMPL(QUuid(TYPELIB), QUuid(APPID));    \
        return impl;                                    \
    } \
    QT_END_NAMESPACE

#define QAXFACTORY_DEFAULT(Class, IIDClass, IIDInterface, IIDEvents, IIDTypeLib, IIDApp) \
    QT_BEGIN_NAMESPACE \
    class QAxDefaultFactory : public QAxFactory \
    { \
    public: \
        QAxDefaultFactory(const QUuid &app, const QUuid &lib) \
        : QAxFactory(app, lib), className(QLatin1String(#Class)) {} \
        QStringList featureList() const override \
        { \
            QStringList list; \
            list << className; \
            return list; \
        } \
        const QMetaObject *metaObject(const QString &key) const override \
        { \
            if (key == className) \
            return &Class::staticMetaObject; \
            return nullptr; \
        } \
        QObject *createObject(const QString &key) override \
        { \
            if (key == className) \
                return new Class(nullptr); \
            return nullptr; \
        } \
        QUuid classID(const QString &key) const override \
        { \
            if (key == className) \
                return QUuid(IIDClass); \
            return QUuid(); \
        } \
        QUuid interfaceID(const QString &key) const override \
        { \
            if (key == className) \
                return QUuid(IIDInterface); \
            return QUuid(); \
        } \
        QUuid eventsID(const QString &key) const override \
        { \
            if (key == className) \
                return QUuid(IIDEvents); \
            return QUuid(); \
        } \
    private: \
        QString className; \
    }; \
    QT_END_NAMESPACE \
    QAXFACTORY_EXPORT(QAxDefaultFactory, IIDTypeLib, IIDApp) \

template<class T>
class QAxClass : public QAxFactory
{
public:
    QAxClass(const QString &libId, const QString &appId)
    : QAxFactory(libId, appId)
    {}

    const QMetaObject *metaObject(const QString &) const override { return &T::staticMetaObject; }
    QStringList featureList() const override { return QStringList(QLatin1String(T::staticMetaObject.className())); }
    QObject *createObject(const QString &key) override
    {
        const QMetaObject &mo = T::staticMetaObject;
        if (key != QLatin1String(mo.className()))
            return nullptr;
        if (!qstrcmp(mo.classInfo(mo.indexOfClassInfo("Creatable")).value(), "no"))
            return nullptr;
        return new T(nullptr);
    }

    void registerClass(const QString &key, QSettings *settings) const override
    {
        const QStringList categories = getImplementedCategories();

        for (const auto &cat : categories) {
            settings->setValue(QLatin1String("/CLSID/") + classID(key).toString()
                               + QLatin1String("/Implemented Categories/") + cat + QLatin1String("/."),
                               QString());
        }
    }

    void unregisterClass(const QString &key, QSettings *settings) const override
    {
        const QStringList categories = getImplementedCategories();

        for (const auto &cat : categories) {
            settings->remove(QLatin1String("/CLSID/") + classID(key).toString()
                             + QLatin1String("/Implemented Categories/") + cat + QLatin1String("/."));
        }
    }

private:
    /*! Retrieve list of comma-separated "Implemented Categories" Q_CLASSINFO UUIDs from T. */
    static QStringList getImplementedCategories()
    {
        const QMetaObject &mo = T::staticMetaObject;
        QString catids = QLatin1String(mo.classInfo(mo.indexOfClassInfo("Implemented Categories")).value());
        return catids.split(QLatin1Char(','));
    }
};

#define QAXFACTORY_BEGIN(IDTypeLib, IDApp) \
    QT_BEGIN_NAMESPACE \
    class QAxFactoryList : public QAxFactory \
    { \
        QStringList factoryKeys; \
        QHash<QString, QAxFactory*> factories; \
        QHash<QString, bool> creatable; \
    public: \
        QAxFactoryList() \
        : QAxFactory(IDTypeLib, IDApp) \
        { \
            QAxFactory *factory = nullptr; \
            QStringList keys; \
            QStringList::Iterator it; \

#define QAXCLASS(Class) \
            factory = new QAxClass<Class>(typeLibID().toString(), appID().toString()); \
            qRegisterMetaType<Class*>(#Class"*"); \
            keys = factory->featureList(); \
            for (const QString &key : qAsConst(keys)) { \
                factoryKeys += key; \
                factories.insert(key, factory); \
                creatable.insert(key, true); \
            }\

#define QAXTYPE(Class) \
            factory = new QAxClass<Class>(typeLibID().toString(), appID().toString()); \
            qRegisterMetaType<Class*>(#Class"*"); \
            keys = factory->featureList(); \
            for (const QString &key : qAsConst(keys)) { \
                factoryKeys += key; \
                factories.insert(key, factory); \
                creatable.insert(key, false); \
            }\

#define QAXFACTORY_END() \
        } \
        ~QAxFactoryList() override { qDeleteAll(factories); } \
        QStringList featureList() const override {  return factoryKeys; } \
        const QMetaObject *metaObject(const QString&key) const override { \
            QAxFactory *f = factories[key]; \
            return f ? f->metaObject(key) : nullptr; \
        } \
        QObject *createObject(const QString &key) override { \
            if (!creatable.value(key)) \
                return nullptr; \
            QAxFactory *f = factories[key]; \
            return f ? f->createObject(key) : nullptr; \
        } \
        QUuid classID(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->classID(key) : QUuid(); \
        } \
        QUuid interfaceID(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->interfaceID(key) : QUuid(); \
        } \
        QUuid eventsID(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->eventsID(key) : QUuid(); \
        } \
        void registerClass(const QString &key, QSettings *s) const override { \
            QAxFactory *f = factories.value(key); \
            if (f) f->registerClass(key, s); \
        } \
        void unregisterClass(const QString &key, QSettings *s) const override { \
            QAxFactory *f = factories.value(key); \
            if (f) f->unregisterClass(key, s); \
        } \
        QString exposeToSuperClass(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->exposeToSuperClass(key) : QString(); \
        } \
        bool stayTopLevel(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->stayTopLevel(key) : false; \
        } \
        bool hasStockEvents(const QString &key) const override { \
            QAxFactory *f = factories.value(key); \
            return f ? f->hasStockEvents(key) : false; \
        } \
    }; \
    QAxFactory *qax_instantiate()               \
    {                                                   \
        QAxFactoryList *impl = new QAxFactoryList();    \
        return impl;                                    \
    } \
    QT_END_NAMESPACE

QT_END_NAMESPACE
QT_WARNING_POP

#ifndef Q_COM_METATYPE_DECLARED
#define Q_COM_METATYPE_DECLARED

Q_DECLARE_OPAQUE_POINTER(IUnknown*)
Q_DECLARE_OPAQUE_POINTER(IDispatch*)

Q_DECLARE_METATYPE(IUnknown*)
Q_DECLARE_METATYPE(IDispatch*)

#endif

#endif // QAXFACTORY_H
