/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef MAVEOD_H
#define MAVEOD_H

#include <QUuid>
#include <QObject>

#include <networkmanager.h>
#include <bluetooth/bluetoothserver.h>

#include "configuration.h"
#include "nymeadservice.h"
#include "hardwaremanager.h"
#include "systemdservice.h"
#include "debugserver.h"
#include "factoryresethandler.h"

class Maveod : public QObject
{
    Q_OBJECT
public:
    enum SystemStatus {
        SystemStatusUninitialized,
        SystemStatusIdle,
        SystemStatusError,
        SystemStatusOffline,
        SystemStatusPoorSignal,
        SystemStatusBluetoothAdvertising,
        SystemStatusBluetoothConnected,
        SystemStatusFactoryResetting
    };
    Q_ENUM(SystemStatus)

    static Maveod* instance();
    void destroy();

    QString configurationFileName() const;
    void setConfigurationFileName(const QString &configurationFileName);

    QString hostName() const;
    QUuid systemUuid() const;

    Configuration *configuration() const;

private:
    explicit Maveod(QObject *parent = nullptr);
    ~Maveod();

    static Maveod *s_instance;

    bool m_initializing = true;

    QString m_configurationFileName;
    QString m_hostName;
    QUuid m_systemUuid;

    Configuration *m_configuration = nullptr;
    NetworkManager *m_networkManager = nullptr;
    BluetoothServer *m_bluetoothServer = nullptr;
    HardwareManager *m_hardwareManager = nullptr;
    NymeadService *m_nymeadService = nullptr;
    SystemdService *m_systemdService = nullptr;
    DebugServer *m_debugServer = nullptr;
    FactoryResetHandler *m_factoryResetHandler = nullptr;

    QTimer *m_advertisingTimer = nullptr;
    int m_advertisingTimeout = 60000;

    QTimer *m_nymeaGracePeriodTimer = nullptr;

    SystemStatus m_systemStatus = SystemStatusUninitialized;

    QString readHostName();
    QUuid readSystemUuid();

    void setSystemStatus(SystemStatus systemStatus, bool force = false);
    void evaluateSystemStatus();

signals:

private slots:
    // Network manager slots
    void onNetworkManagerAvailableChanged(bool available);
    void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state);
    void onNetworkManagerConnectivityStateChanged(const NetworkManager::NetworkManagerConnectivityState &connectivityState);

    // Hardware manager slots
    void onUserButtonClicked();
    void onUserButtonLongPressed();
    void onResetButtonClicked();
    void onResetButtonLongPressed();

    // Bluetooth server slots
    void onBluetoothServerRunningChanged(bool running);
    void onBluetoothServerClientConnectedChanged(bool connected);

    // Nymead service
    void onNymeaServiceAvailableChanged(bool available);

    void onAdvertisingTimeout();

    void postRun();

public slots:
    void run();

};

#endif // MAVEOD_H
