#include <QApplication>
#include <fmp_manager_i.h>
#include <QDebug>
#include <QPluginLoader>
#include <QSettings>
#include <QDir>
#include <QDirIterator>
#include <qtservice.h>
#include "../fmp_settings/fmp_settings_def.h"

class FMPService : public QtService<QApplication>
{
public:
    FMPService(int argc, char**argv, const QString &svcname) :
        _starttype(0),
        _name(svcname),
        _setting(0),
        QtService<QApplication>(argc, argv, svcname)
    {
        createApplication(argc, argv);
        _setting = new QSettings(qApp->applicationDirPath() + "/fmPos.ini", QSettings::IniFormat);
        _starttype = _setting->value(FMP_INIKEY_SERVICESTARTTYPE, 0).toInt();
        _description = _setting->value(FMP_INIKEY_SERVICEDESC, "Freemud POS plugin service").toString();
        _plugin_path = _setting->value(FMP_INIKEY_PLUGINPATH, "plugins").toString();
        _entry_plugin = _setting->value(FMP_INIKEY_ENTRYSERVICE, "com.fmp.home").toString();

        setStartupType((QtServiceController::StartupType)_starttype);
        setServiceDescription(_description);
    }

    void start()
    {
        QString manager_plugin_path = getPluginPath("fmp.manager");
        QPluginLoader fmp_manager_plugin(manager_plugin_path);
        FMPManagerInterface *fmp_manager = qobject_cast<FMPManagerInterface*>(fmp_manager_plugin.instance());
        if (!fmp_manager) {
            QString msg = "Failed loading plugin:\n";
            msg += manager_plugin_path + "\n";
            msg += fmp_manager_plugin.errorString();
            logMessage(msg , QtServiceBase::Error);
        }
        else {
            FMPProps props;
            props[FMP_PROPKEY_PLUGINPATH]   = _plugin_path;
            props[FMP_PROPKEY_ENTRY]        = _entry_plugin;
            props[FMP_PROPKEY_CFG]          = _setting->fileName();
            if (FMP_SUCCESS != fmp_manager->SetProperties(props)
                    || FMP_SUCCESS != fmp_manager->StartService()) {
                exit(0);
            }
        }
    }

    QString getPluginPath(const QString &plugin_name)
    {
        QString plugin_file_name(plugin_name);
        plugin_file_name.replace(".", "_");
        QStringList filters;
#ifdef Q_OS_WIN
        filters << plugin_file_name + "*" + ".dll";
#else
#   ifdef Q_OS_LINUX
        filters << plugin_file_name + "*" + ".so";
#   else
        filters << plugin_file_name + "*" + ".dylib";
#   endif
#endif
        QDirIterator dir_iter(qApp->applicationDirPath() + "/" + _plugin_path, filters, QDir::Files);
        QString plugin_version;
        QFileInfo plugin_file_info;
        while(dir_iter.hasNext()) {
            dir_iter.next();
            QFileInfo file_info = dir_iter.fileInfo();
            QString file_basename = file_info.completeBaseName();
            if (file_basename.startsWith("lib")) file_basename = file_basename.mid(3);
            QString tmp_ver = file_basename.section(plugin_file_name, 1, 1).replace("_", "");
            if (plugin_version.isEmpty() || plugin_version < tmp_ver) {
                plugin_version = tmp_ver;
                plugin_file_info = file_info;
            }
        }

        return plugin_file_info.canonicalFilePath();
    }

protected:
    virtual void createApplication(int &argc, char **argv)
    {
        if (!application()) {
            QtService::createApplication(argc, argv);
        }
    }
private:
    int         _starttype;
    QSettings  *_setting;

    QString     _name;
    QString     _description;
    QString     _plugin_path;
    QString     _entry_plugin;
    QString     _plugin_suffix;
};

#define SERVICE 0

int main(int argc, char** argv)
{
    QString appPath = QString::fromLocal8Bit(argv[0]);
    appPath.replace("\\", "/");
    appPath = appPath.section("/", 0, -2);
    QSettings setting(appPath + "/fmPos.ini", QSettings::IniFormat);
    QString svc_name = setting.value(FMP_INIKEY_SERVICENAME, "FMPService").toString();

    FMPService svc(argc, argv, svc_name);

#if SERVICE
    return svc->exec();
#else
    svc.start();
    return qApp->exec();
#endif

}
