#ifdef _WIN32
#   define MINGW_HAS_SECURE_API 1
#   include "opentrack-library-path.h"
#   include <stdlib.h>
#   include <vector>
#   include <QCoreApplication>
#   include <QFile>
#   include <QString>
#endif

#include "ui.h"
#include "opentrack-compat/options.hpp"
using namespace options;
#include <QApplication>
#include <QCommandLineParser>
#include <QStyleFactory>
#include <QStringList>
#include <QMessageBox>
#include <memory>
#include <cstring>

#ifdef _WIN32
// workaround QTBUG-38598, allow for launching from another directory
static void add_program_library_path()
{
    char* p = _pgmptr;
    char path[MAX_PATH+1];
    strcpy(path, p);
    char* ptr = strrchr(path, '\\');
    if (ptr)
    {
        *ptr = '\0';
        QCoreApplication::addLibraryPath(path);
    }
}
#endif

int main(int argc, char** argv)
{
#ifdef _WIN32
    add_program_library_path();
#elif !defined(__linux)
    // workaround QTBUG-38598
    QCoreApplication::addLibraryPath(".");
#endif

#if defined(_WIN32) || defined(__APPLE__)
    // qt5 designer-made controls look like shit on 'doze -sh 20140921
    // also our OSX look leaves a lot to be desired -sh 20150726
    {
        const QStringList preferred { "fusion", "windowsvista", "macintosh", "windowsxp" };
        for (const auto& style_name : preferred)
        {
            QStyle* s = QStyleFactory::create(style_name);
            if (s)
            {
                QApplication::setStyle(s);
                break;
            }
        }
    }
#endif

    QApplication::setAttribute(Qt::AA_X11InitThreads, true);
    QApplication app(argc, argv);

#ifdef _WIN32
    // see https://software.intel.com/en-us/articles/limitation-to-the-length-of-the-system-path-variable
    static char env_path[4096] { '\0', };
    {
        QString lib_path = OPENTRACK_BASE_PATH;
        lib_path.replace("/", "\\");
        const QByteArray lib_path_ = QFile::encodeName(lib_path);

        QString mod_path = OPENTRACK_BASE_PATH + QString(OPENTRACK_LIBRARY_PATH);
        mod_path.replace("/", "\\");
        const QByteArray mod_path_ = QFile::encodeName(mod_path);

        std::vector<const char*> contents
        {
            "PATH=",
            lib_path_.constData(),
            ";",
            mod_path_.constData(),
            ";",
            getenv("PATH"),
        };

        bool ok = true;

        for (const char* ptr : contents)
        {
            strcat_s(env_path, sizeof(env_path), ptr);

            if (ptr == nullptr || ptr[0] == '\0' || env_path[0] == '\0')
            {
                qDebug() << "bad path element, debug info:"
                         << (ptr == nullptr ? "<null>" : ptr)
                         << (ptr != nullptr && ptr[0] == '\0')
                         << (env_path[0] == '\0');
                ok = false;
                break;
            }
        }

        if (ok)
        {
            const int error = _putenv(env_path);

            if (error)
                qDebug() << "can't _putenv win32 path";
        }
        else
            qDebug() << "can't set win32 path";
    }
#endif

    MainWindow::set_working_directory();

    auto w = std::make_shared<MainWindow>();

    w->show();
    app.exec();

    // on MSVC crashes in atexit
#ifdef _MSC_VER
    TerminateProcess(GetCurrentProcess(), 0);
#endif
    return 0;
}