/*
 * Copyright 2013-2014 Canonical Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 3 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef TRANSFERS_LIB_NETWORK_SESSION_H
#define TRANSFERS_LIB_NETWORK_SESSION_H

#include <QMutex>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QNetworkInformation>
#else
#include <QNetworkConfigurationManager>
#endif
#include <QObject>

#include "nm_interface.h"

namespace Lomiri {

namespace Transfers {

namespace System {

class NetworkSession : public QObject {
    Q_OBJECT

 public:
    ~NetworkSession();

    virtual bool isError();
    virtual bool isOnline();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    virtual QNetworkInformation::TransportMedium sessionType();
#else
    virtual QNetworkConfiguration::BearerType sessionType();
#endif

    static NetworkSession* instance();

    // only used for testing so that we can inject a fake
    static void setInstance(NetworkSession* instance);
    static void deleteInstance();

 Q_SIGNALS:
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    void sessionTypeChanged(QNetworkInformation::TransportMedium type);
#else
    void sessionTypeChanged(QNetworkConfiguration::BearerType type);
#endif
    void onlineStateChanged(bool state);

 protected:
    explicit NetworkSession(QObject* parent=0);

 private:
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QNetworkInformation::TransportMedium convertNMString(const QString& str);
    void onReachabilityChanged();
#else
    QNetworkConfiguration::BearerType convertNMString(const QString& str);
#endif
    void onPropertiesChanged(const QVariantMap& changedProperties);

 private:
    // used for the singleton
    static NetworkSession* _instance;
    static QMutex _mutex;

    NMInterface* _nm = nullptr;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QNetworkInformation::TransportMedium _sessionType =
        QNetworkInformation::TransportMedium::Unknown;
#else
    QNetworkConfigurationManager* _configManager = nullptr;
    QNetworkConfiguration::BearerType _sessionType =
        QNetworkConfiguration::BearerUnknown;
#endif
    bool _error = false;
    QString _errorMsg = QString();
};

}

}

}

#endif
