/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore 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 "qplatformdefs.h"

#include "qplugin.h"
#include "qcoreapplication.h"
#include "qpluginloader.h"
#include <qfileinfo.h>
#include "qfactoryloader_p.h"
#include "qdebug.h"
#include "qdir.h"

QT_BEGIN_NAMESPACE

#if QT_CONFIG(library)

/*!
    \class QPluginLoader
    \inmodule QtCore
    \reentrant
    \brief The QPluginLoader class loads a plugin at run-time.


    \ingroup plugins

    QPluginLoader provides access to a \l{How to Create Qt
    Plugins}{Qt plugin}. A Qt plugin is stored in a shared library (a
    DLL) and offers these benefits over shared libraries accessed
    using QLibrary:

    \list
    \li QPluginLoader checks that a plugin is linked against the same
       version of Qt as the application.
    \li QPluginLoader provides direct access to a root component object
       (instance()), instead of forcing you to resolve a C function manually.
    \endlist

    An instance of a QPluginLoader object operates on a single shared
    library file, which we call a plugin. It provides access to the
    functionality in the plugin in a platform-independent way. To
    specify which plugin to load, either pass a file name in
    the constructor or set it with setFileName().

    The most important functions are load() to dynamically load the
    plugin file, isLoaded() to check whether loading was successful,
    and instance() to access the root component in the plugin. The
    instance() function implicitly tries to load the plugin if it has
    not been loaded yet. Multiple instances of QPluginLoader can be
    used to access the same physical plugin.

    Once loaded, plugins remain in memory until all instances of
    QPluginLoader has been unloaded, or until the application
    terminates. You can attempt to unload a plugin using unload(),
    but if other instances of QPluginLoader are using the same
    library, the call will fail, and unloading will only happen when
    every instance has called unload(). Right before the unloading
    happens, the root component will also be deleted.

    See \l{How to Create Qt Plugins} for more information about
    how to make your application extensible through plugins.

    Note that the QPluginLoader cannot be used if your application is
    statically linked against Qt. In this case, you will also have to
    link to plugins statically. You can use QLibrary if you need to
    load dynamic libraries in a statically linked application.

    \sa QLibrary, {Plug & Paint Example}
*/

/*!
    \class QStaticPlugin
    \inmodule QtCore
    \since 5.2

    \brief QStaticPlugin is a struct containing a reference to a
    static plugin instance together with its meta data.

    \sa QPluginLoader, {How to Create Qt Plugins}
*/

/*!
    \fn QObject *QStaticPlugin::instance()

    Returns the plugin instance.

    \sa QPluginLoader::staticInstances()
*/

/*!
    \fn const char *QStaticPlugin::rawMetaData()

    Returns the raw meta data for the plugin.

    \sa metaData(), Q_PLUGIN_METADATA()
*/

/*!
    Constructs a plugin loader with the given \a parent.
*/
QPluginLoader::QPluginLoader(QObject *parent)
    : QObject(parent), d(0), did_load(false)
{
}

/*!
    Constructs a plugin loader with the given \a parent that will
    load the plugin specified by \a fileName.

    To be loadable, the file's suffix must be a valid suffix for a
    loadable library in accordance with the platform, e.g. \c .so on
    Unix, - \c .dylib on \macos and iOS, and \c .dll on Windows. The suffix
    can be verified with QLibrary::isLibrary().

    \sa setFileName()
*/
QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent)
    : QObject(parent), d(0), did_load(false)
{
    setFileName(fileName);
    setLoadHints(QLibrary::PreventUnloadHint);
}

/*!
    Destroys the QPluginLoader object.

    Unless unload() was called explicitly, the plugin stays in memory
    until the application terminates.

    \sa isLoaded(), unload()
*/
QPluginLoader::~QPluginLoader()
{
    if (d)
        d->release();
}

/*!
    Returns the root component object of the plugin. The plugin is
    loaded if necessary. The function returns \nullptr if the plugin could
    not be loaded or if the root component object could not be
    instantiated.

    If the root component object was destroyed, calling this function
    creates a new instance.

    The root component, returned by this function, is not deleted when
    the QPluginLoader is destroyed. If you want to ensure that the root
    component is deleted, you should call unload() as soon you don't
    need to access the core component anymore.  When the library is
    finally unloaded, the root component will automatically be deleted.

    The component object is a QObject. Use qobject_cast() to access
    interfaces you are interested in.

    \sa load()
*/
QObject *QPluginLoader::instance()
{
    if (!isLoaded() && !load())
        return 0;
    if (!d->inst && d->instance)
        d->inst = d->instance();
    return d->inst.data();
}

/*!
    Returns the meta data for this plugin. The meta data is data specified
    in a json format using the Q_PLUGIN_METADATA() macro when compiling
    the plugin.

    The meta data can be queried in a fast and inexpensive way without
    actually loading the plugin. This makes it possible to e.g. store
    capabilities of the plugin in there, and make the decision whether to
    load the plugin dependent on this meta data.
 */
QJsonObject QPluginLoader::metaData() const
{
    if (!d)
        return QJsonObject();
    return d->metaData;
}

/*!
    Loads the plugin and returns \c true if the plugin was loaded
    successfully; otherwise returns \c false. Since instance() always
    calls this function before resolving any symbols it is not
    necessary to call it explicitly. In some situations you might want
    the plugin loaded in advance, in which case you would use this
    function.

    \sa unload()
*/
bool QPluginLoader::load()
{
    if (!d || d->fileName.isEmpty())
        return false;
    if (did_load)
        return d->pHnd && d->instance;
    if (!d->isPlugin())
        return false;
    did_load = true;
    return d->loadPlugin();
}


/*!
    Unloads the plugin and returns \c true if the plugin could be
    unloaded; otherwise returns \c false.

    This happens automatically on application termination, so you
    shouldn't normally need to call this function.

    If other instances of QPluginLoader are using the same plugin, the
    call will fail, and unloading will only happen when every instance
    has called unload().

    Don't try to delete the root component. Instead rely on
    that unload() will automatically delete it when needed.

    \sa instance(), load()
*/
bool QPluginLoader::unload()
{
    if (did_load) {
        did_load = false;
        return d->unload();
    }
    if (d)  // Ouch
        d->errorString = tr("The plugin was not loaded.");
    return false;
}

/*!
    Returns \c true if the plugin is loaded; otherwise returns \c false.

    \sa load()
 */
bool QPluginLoader::isLoaded() const
{
    return d && d->pHnd && d->instance;
}

#if defined(QT_SHARED)
static QString locatePlugin(const QString& fileName)
{
    const bool isAbsolute = QDir::isAbsolutePath(fileName);
    if (isAbsolute) {
        QFileInfo fi(fileName);
        if (fi.isFile()) {
            return fi.canonicalFilePath();
        }
    }
    QStringList prefixes = QLibraryPrivate::prefixes_sys();
    prefixes.prepend(QString());
    QStringList suffixes = QLibraryPrivate::suffixes_sys(QString());
    suffixes.prepend(QString());

    // Split up "subdir/filename"
    const int slash = fileName.lastIndexOf(QLatin1Char('/'));
    const QStringRef baseName = fileName.midRef(slash + 1);
    const QStringRef basePath = isAbsolute ? QStringRef() : fileName.leftRef(slash + 1); // keep the '/'

    const bool debug = qt_debug_component();

    QStringList paths;
    if (isAbsolute) {
        paths.append(fileName.left(slash)); // don't include the '/'
    } else {
        paths = QCoreApplication::libraryPaths();
    }

    for (const QString &path : qAsConst(paths)) {
        for (const QString &prefix : qAsConst(prefixes)) {
            for (const QString &suffix : qAsConst(suffixes)) {
#ifdef Q_OS_ANDROID
                {
                    QString pluginPath = basePath + prefix + baseName + suffix;
                    const QString fn = path + QLatin1String("/lib") + pluginPath.replace(QLatin1Char('/'), QLatin1Char('_'));
                    if (debug)
                        qDebug() << "Trying..." << fn;
                    if (QFileInfo(fn).isFile())
                        return fn;
                }
#endif
                const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix;
                if (debug)
                    qDebug() << "Trying..." << fn;
                if (QFileInfo(fn).isFile())
                    return fn;
            }
        }
    }
    if (debug)
        qDebug() << fileName << "not found";
    return QString();
}
#endif

/*!
    \property QPluginLoader::fileName
    \brief the file name of the plugin

    We recommend omitting the file's suffix in the file name, since
    QPluginLoader will automatically look for the file with the appropriate
    suffix (see QLibrary::isLibrary()).

    When loading the plugin, QPluginLoader searches
    in all plugin locations specified by QCoreApplication::libraryPaths(),
    unless the file name has an absolute path. After loading the plugin
    successfully, fileName() returns the fully-qualified file name of
    the plugin, including the full path to the plugin if one was given
    in the constructor or passed to setFileName().

    If the file name does not exist, it will not be set. This property
    will then contain an empty string.

    By default, this property contains an empty string.

    \sa load()
*/
void QPluginLoader::setFileName(const QString &fileName)
{
#if defined(QT_SHARED)
    QLibrary::LoadHints lh = QLibrary::PreventUnloadHint;
    if (d) {
        lh = d->loadHints();
        d->release();
        d = 0;
        did_load = false;
    }

    const QString fn = locatePlugin(fileName);

    d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
    if (!fn.isEmpty())
        d->updatePluginState();

#else
    if (qt_debug_component()) {
        qWarning("Cannot load %s into a statically linked Qt library.",
            (const char*)QFile::encodeName(fileName));
    }
    Q_UNUSED(fileName);
#endif
}

QString QPluginLoader::fileName() const
{
    if (d)
        return d->fileName;
    return QString();
}

/*!
    \since 4.2

    Returns a text string with the description of the last error that occurred.
*/
QString QPluginLoader::errorString() const
{
    return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString;
}

/*! \since 4.4

    \property QPluginLoader::loadHints
    \brief Give the load() function some hints on how it should behave.

    You can give hints on how the symbols in the plugin are
    resolved. By default since Qt 5.7, QLibrary::PreventUnloadHint is set.

    See the documentation of QLibrary::loadHints for a complete
    description of how this property works.

    \sa QLibrary::loadHints
*/

void QPluginLoader::setLoadHints(QLibrary::LoadHints loadHints)
{
    if (!d) {
        d = QLibraryPrivate::findOrCreate(QString());   // ugly, but we need a d-ptr
        d->errorString.clear();
    }
    d->setLoadHints(loadHints);
}

QLibrary::LoadHints QPluginLoader::loadHints() const
{
    return d ? d->loadHints() : QLibrary::LoadHints();
}

#endif // QT_CONFIG(library)

typedef QVector<QStaticPlugin> StaticPluginList;
Q_GLOBAL_STATIC(StaticPluginList, staticPluginList)

/*!
    \relates QPluginLoader
    \since 5.0

    Registers the \a plugin specified with the plugin loader, and is used
    by Q_IMPORT_PLUGIN().
*/
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin plugin)
{
    staticPluginList()->append(plugin);
}

/*!
    Returns a list of static plugin instances (root components) held
    by the plugin loader.
    \sa staticPlugins()
*/
QObjectList QPluginLoader::staticInstances()
{
    QObjectList instances;
    const StaticPluginList *plugins = staticPluginList();
    if (plugins) {
        const int numPlugins = plugins->size();
        instances.reserve(numPlugins);
        for (int i = 0; i < numPlugins; ++i)
            instances += plugins->at(i).instance();
    }
    return instances;
}

/*!
    Returns a list of QStaticPlugins held by the plugin
    loader. The function is similar to \l staticInstances()
    with the addition that a QStaticPlugin also contains
    meta data information.
    \sa staticInstances()
*/
QVector<QStaticPlugin> QPluginLoader::staticPlugins()
{
    StaticPluginList *plugins = staticPluginList();
    if (plugins)
        return *plugins;
    return QVector<QStaticPlugin>();
}

/*!
    Returns a the meta data for the plugin as a QJsonObject.

    \sa rawMetaData()
*/
QJsonObject QStaticPlugin::metaData() const
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    // the data is already loaded, so this doesn't matter
    qsizetype rawMetaDataSize = INT_MAX;
    const char *ptr = rawMetaData();
#else
    auto ptr = static_cast<const char *>(rawMetaData);
#endif

    QString errMsg;
    QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize, &errMsg);
    Q_ASSERT(doc.isObject());
    Q_ASSERT(errMsg.isEmpty());
    return doc.object();
}

QT_END_NAMESPACE

#include "moc_qpluginloader.cpp"
