#include "pluginloader.h"

PluginLoader::PluginLoader(QString fileName, QObject *parent)
    : QObject{parent}
    , m_pLoader(new QPluginLoader(fileName, parent))
{
    /**
     *  QPluginLoader 默认持有 PreventUnloadHint 标志，该标志阻止 DLL 被真正卸载
     *  使用 setLoadHints 清除 PreventUnloadHint 标志
     */

    m_pLoader->setLoadHints(QLibrary::ResolveAllSymbolsHint);
}

PluginLoader::~PluginLoader()
{
    if(m_pLoader->isLoaded())
        m_pLoader->unload();
    delete m_pLoader;
    m_customWidgets.clear();
}

bool PluginLoader::load()
{
    if(m_pLoader->load())
    {
        QObject *instance = m_pLoader->instance();

        if(auto collection = qobject_cast<QDesignerCustomWidgetCollectionInterface *>(instance))
        {
            m_customWidgets << collection->customWidgets();
        }
        else if(auto single = qobject_cast<QDesignerCustomWidgetInterface *>(instance))
        {
            m_customWidgets << single;
        }
        else
        {
            return false;
        }
        return true;
    }
    return false;
}

bool PluginLoader::unload()
{
    m_customWidgets.clear();
    if(m_pLoader)
        return m_pLoader->unload();
    return false;
}

bool PluginLoader::isLoaded() const
{
    if(m_pLoader)
        return m_pLoader->isLoaded();
    return false;
}

const QObject *PluginLoader::instance()
{
    if(m_pLoader)
        return m_pLoader->instance();
    return nullptr;
}

QString PluginLoader::fileName() const
{
    if(m_pLoader)
        return m_pLoader->fileName();
    return QString();
}

QString PluginLoader::errorString() const
{
    if(m_pLoader)
        return m_pLoader->errorString();
    else
        return QString("plugin loader is nullptr.");
}

QList<QDesignerCustomWidgetInterface *> PluginLoader::customWidgets() const
{
    return m_customWidgets;
}