/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of maveod.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "maveod.h"
#include "application.h"
#include "loggingcategories.h"

#include <signal.h>
#include <unistd.h>
#include <execinfo.h>

static bool s_aboutToShutdown = false;

static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vector<int>& ignoreSignals = std::vector<int>())
{
    auto handler = [](int sig) -> void {
        switch (sig) {
        case SIGQUIT:
            qCDebug(dcMaveod()) << "Cought SIGQUIT quit signal...";
            break;
        case SIGINT:
            qCDebug(dcMaveod()) << "Cought SIGINT quit signal...";
            break;
        case SIGTERM:
            qCDebug(dcMaveod()) << "Cought SIGTERM quit signal...";
            break;
        case SIGHUP:
            qCDebug(dcMaveod()) << "Cought SIGHUP quit signal...";
            break;
        default:
            break;
        }

        if (s_aboutToShutdown) {
            qCCritical(dcMaveod()) << "Already shutting down.";
            return;
        }

        qCDebug(dcMaveod()) << "=====================================";
        qCDebug(dcMaveod()) << "Shutting down";
        qCDebug(dcMaveod()) << "=====================================";
        s_aboutToShutdown = true;

        Maveod::instance()->destroy();
        Application::quit();
    };

    // all these signals will be ignored.
    for (int sig : ignoreSignals)
        signal(sig, SIG_IGN);

    for (int sig : quitSignals) {
        signal(sig, handler);
    }

}

Application::Application(int &argc, char **argv) :
    QCoreApplication(argc, argv)
{
    catchUnixSignals({SIGQUIT, SIGINT, SIGTERM, SIGHUP});
}
