#include "configmanager.h"
#include "private/configmanager_p.h"

#include <QStandardPaths>
#include <QApplication>
#include <QFileInfo>
#include <QSettings>
#include <QDir>
#include <QDebug>

UOSAI_USE_NAMESPACE

ConfigManagerPrivate::ConfigManagerPrivate(QObject *parent)
    : QObject(parent)
{
}

QVariant ConfigManagerPrivate::value(const QString &group, const QString &key) const
{
    QReadLocker rlk(&mutex);
    set->beginGroup(group);
    QVariant value = set->value(key);
    set->endGroup();
    return value;
}

void ConfigManagerPrivate::setDefaultConfig()
{
    if (set) {
        set->beginGroup(WORDWIZARD_GROUP);
        set->setValue(WORDWIZARD_ISFIRSTCLOSE, true);
        set->setValue(WORDWIZARD_ISHIDDEN, false);
        set->endGroup();

        set->beginGroup(AIBAR_GROUP);
        set->setValue(AIBAR_ENABLEFILEDRAG, true);
        set->endGroup();
    }
}

ConfigManager::ConfigManager(QObject *parent)
    : QObject(parent),
      d(new ConfigManagerPrivate(this))
{
}

void ConfigManager::init()
{
    d->delayLoadTimer.setSingleShot(true);
    d->delayLoadTimer.setInterval(50);
    connect(&d->delayLoadTimer, &QTimer::timeout, this, &ConfigManager::loadConfig);

    auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
    d->configPath = configPath = configPath
            + "/" + qApp->organizationName()
            + "/" + qApp->applicationName()
            + "/" + qApp->applicationName() + ".conf";

    d->set = new QSettings(d->configPath, QSettings::IniFormat);

    QFileInfo configFile(configPath);
    if (!configFile.exists()) {
        configFile.absoluteDir().mkpath(".");

        //生成文件
        QFile file(configPath);
        file.open(QFile::NewOnly);
        file.close();
        d->setDefaultConfig();
        qInfo() << "create conf " << configPath;
    } else
        checkConfigValue();

    d->set->sync();

    if (d->configWatcher)
        delete d->configWatcher;

    d->configWatcher = new QFileSystemWatcher(this);
    d->configWatcher->addPath(configFile.absolutePath());
    d->configWatcher->addPath(configFile.absoluteFilePath());
    connect(d->configWatcher, &QFileSystemWatcher::fileChanged, this, &ConfigManager::onFileChanged);
    connect(d->configWatcher, &QFileSystemWatcher::directoryChanged, this, &ConfigManager::onFileChanged);
}

ConfigManager *ConfigManager::instance()
{
    static ConfigManager ins;
    return &ins;
}

QVariant ConfigManager::value(const QString &group, const QString &key) const
{
    return d->value(group, key);
}

void ConfigManager::onFileChanged(const QString &file)
{
    qInfo() << "The configuration file changed: " << file;
    d->delayLoadTimer.start();
}

void ConfigManager::loadConfig()
{
    if (d->configPath.isEmpty())
        return;
    QFileInfo configFile(d->configPath);
    if (!configFile.exists())
        return;

    if (d->set) {
        delete d->set;
        d->set = nullptr;
    }
    d->set = new QSettings(d->configPath, QSettings::IniFormat);
}

void ConfigManager::setValue(const QString &group, const QString &key,const QVariant &value)
{
    d->set->beginGroup(group);
    d->set->setValue(key, value);
    d->set->endGroup();
}

void ConfigManager::checkConfigValue()
{
    if (value(WORDWIZARD_GROUP, WORDWIZARD_ISFIRSTCLOSE).isNull()) {
        setValue(WORDWIZARD_GROUP, WORDWIZARD_ISFIRSTCLOSE, true);
    }
    if (value(WORDWIZARD_GROUP, WORDWIZARD_ISHIDDEN).isNull()) {
        setValue(WORDWIZARD_GROUP, WORDWIZARD_ISHIDDEN, false);
    }
    if (value(AIBAR_GROUP, AIBAR_ENABLEFILEDRAG).isNull()) {
        setValue(AIBAR_GROUP, AIBAR_ENABLEFILEDRAG, true);
    }
}

