/* This file was generated by ecm_create_qm_loader(). DO NOT EDIT!
 *
 * Building this file in a library ensures translations are automatically loaded
 * when an application makes use of the library.
 *
 *
 * SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
 * SPDX-FileCopyrightText: 2015 Alex Merry <alex.merry@kde.org>
 * SPDX-FileCopyrightText: 2023 Ingo Klöcker <kloecker@kde.org>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <QCoreApplication>
#include <QLocale>
#include <QStandardPaths>
#include <QThread>
#include <QTranslator>
#include <QDir>

namespace {

    static QLocale getSystemLocale()
    {
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
        // On Windows and Apple OSs, we cannot use QLocale::system() if an application-specific
        // language was set by kxmlgui because Qt ignores LANGUAGE on Windows and Apple OSs.
        // The following code is a simplified variant of QSystemLocale::fallbackUiLocale()
        // (in qlocale_unix.cpp) ignoring LC_ALL, LC_MESSAGES, and LANG.
        QString language = qEnvironmentVariable("LANGUAGE");
        if (!language.isEmpty()) {
            language = language.split(QLatin1Char{':'}).constFirst();
            if (!language.isEmpty()) {
                return QLocale{language};
            }
        }
#endif
        return QLocale::system();
    }

    enum class LoadOptions { CreateWatcher, DoNotCreateWatcher };

    void load(LoadOptions options);

    class LanguageChangeWatcher : public QObject
    {
    public:
        LanguageChangeWatcher(QObject *parent) : QObject(parent)
        {
            m_loadedLocale = getSystemLocale().name();
            QCoreApplication::instance()->installEventFilter(this);
        }

    private:
        bool eventFilter(QObject *obj, QEvent *event) override
        {
            if (event->type() == QEvent::LanguageChange) {
                const auto systemLocaleName = getSystemLocale().name();
                if (m_loadedLocale != systemLocaleName) {
                    m_loadedLocale = systemLocaleName;
                    load(LoadOptions::DoNotCreateWatcher);
                }
            }
            return QObject::eventFilter(obj, event);
        }


        QString m_loadedLocale;
    };

    bool loadTranslation(const QString &localeDirName)
    {
        QString subPath = QStringLiteral("locale/") + localeDirName + QStringLiteral("/LC_MESSAGES/@QM_LOADER_CATALOG_NAME@.qm");

#if defined(Q_OS_ANDROID)
        const QString fullPath = QStringLiteral("assets:/share/") + subPath;
        if (!QFile::exists(fullPath)) {
            return false;
        }
#else
# ifdef Q_OS_MACOS
        const QString fullPath = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, subPath);
# else
        const QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath);
# endif
        if (fullPath.isEmpty()) {
            return false;
        }
#endif
        QTranslator *translator = new QTranslator(QCoreApplication::instance());
        if (!translator->load(fullPath)) {
            delete translator;
            return false;
        }
        QCoreApplication::instance()->installTranslator(translator);
        return true;
    }

    void load(LoadOptions options)
    {
        // The way Qt translation system handles plural forms makes it necessary to
        // have a translation file which contains only plural forms for `en`. That's
        // why we load the `en` translation unconditionally, then load the
        // translation for the current locale to overload it.
        loadTranslation(QStringLiteral("en"));

        auto langs = getSystemLocale().uiLanguages();

        for (int i = 0; i < langs.size(); i++) {
            langs[i].replace(QLatin1Char('-'), QLatin1Char('_'));
            const auto idx = langs[i].indexOf(QLatin1Char('_'));
            if (idx > 0) {
                // insert the country stripped language to the ideal position,
                // that is, after the same language dialects.
                // if langs is [pt_Latn_BR, pt_BR], the pt should be inserted
                // after pt_BR
                const QString genericLang = langs[i].left(idx);
                int j = i + 1;
                int insertIdx = j;
                bool found = false;
                while (j < langs.size()) {
                    if (langs[j] == genericLang) {
                        found = true;
                        break;
                    }
                    if (langs[j].startsWith(genericLang)) {
                        insertIdx = j + 1;
                    }
                    j++;
                }
                if (!found) {
                    langs.insert(insertIdx, genericLang);
                }
            }
        }
        langs.removeDuplicates();
        for (const auto &lang :
#if QT_VERSION_MAJOR == 5
                qAsConst(langs)
#else
                std::as_const(langs)
#endif
                ) {
            if (lang == QLatin1String("en") || loadTranslation(lang)) {
                break;
            }
        }

        if (options == LoadOptions::CreateWatcher) {
            new LanguageChangeWatcher(QCoreApplication::instance());
        }
    }

    void loadOnMainThread()
    {
        // If this library is loaded after the QCoreApplication instance is
        // created (eg: because it is brought in by a plugin), there is no
        // guarantee this function will be called on the main thread.
        // QCoreApplication::installTranslator needs to be called on the main
        // thread, because it uses QCoreApplication::sendEvent.
        if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
            load(LoadOptions::CreateWatcher);
        } else {
            QMetaObject::invokeMethod(QCoreApplication::instance(), [] { load(LoadOptions::CreateWatcher); }, Qt::QueuedConnection);
        }
    }
}

Q_COREAPP_STARTUP_FUNCTION(loadOnMainThread)
