/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtPositioning module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qgeopositioninfosource.h>
#include "qgeopositioninfosource_p.h"
#include "qgeopositioninfosourcefactory.h"

#include <QFile>
#include <QPluginLoader>
#include <QStringList>
#include <QJsonObject>
#include <QCryptographicHash>
#include <QtCore/private/qfactoryloader_p.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
        ("org.qt-project.qt.position.sourcefactory/5.0",
         QLatin1String("/position")))

/*!
    \class QGeoPositionInfoSource
    \inmodule QtPositioning
    \ingroup QtPositioning-positioning
    \since 5.2

    \brief The QGeoPositionInfoSource class is an abstract base class for the distribution of positional updates.

    The static function QGeoPositionInfoSource::createDefaultSource() creates a default
    position source that is appropriate for the platform, if one is available.
    Otherwise, QGeoPositionInfoSource will check for available plugins that
    implement the QGeoPositionInfoSourceFactory interface.

    Users of a QGeoPositionInfoSource subclass can request the current position using
    requestUpdate(), or start and stop regular position updates using
    startUpdates() and stopUpdates(). When an update is available,
    positionUpdated() is emitted. The last known position can be accessed with
    lastKnownPosition().

    If regular position updates are required, setUpdateInterval() can be used
    to specify how often these updates should be emitted. If no interval is
    specified, updates are simply provided whenever they are available.
    For example:

    \code
        // Emit updates every 10 seconds if available
        QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0);
        if (source)
            source->setUpdateInterval(10000);
    \endcode

    To remove an update interval that was previously set, call
    setUpdateInterval() with a value of 0.

    Note that the position source may have a minimum value requirement for
    update intervals, as returned by minimumUpdateInterval().
*/

/*!
    \enum QGeoPositionInfoSource::PositioningMethod
    Defines the types of positioning methods.

    \value NoPositioningMethods None of the positioning methods.
    \value SatellitePositioningMethods Satellite-based positioning methods such as GPS or GLONASS.
    \value NonSatellitePositioningMethods Other positioning methods such as 3GPP cell identifier or WiFi based positioning.
    \value AllPositioningMethods Satellite-based positioning methods as soon as available. Otherwise non-satellite based methods.
*/

QGeoPositionInfoSourcePrivate *QGeoPositionInfoSourcePrivate::get(const QGeoPositionInfoSource &source)
{
    return source.d;
}

QGeoPositionInfoSourcePrivate::~QGeoPositionInfoSourcePrivate()
{

}

void QGeoPositionInfoSourcePrivate::loadMeta()
{
    metaData = plugins().value(providerName);
}

void QGeoPositionInfoSourcePrivate::loadPlugin()
{
    int idx = int(metaData.value(QStringLiteral("index")).toDouble());
    if (idx < 0)
        return;
    QObject *instance = loader()->instance(idx);
    if (!instance)
        return;
    factoryV2 = qobject_cast<QGeoPositionInfoSourceFactoryV2 *>(instance);
    if (!factoryV2)
        factory = qobject_cast<QGeoPositionInfoSourceFactory *>(instance);
    else
        factory = factoryV2;
}

bool QGeoPositionInfoSourcePrivate::setBackendProperty(const QString &/*name*/, const QVariant & /*value*/)
{
    return false;
}

QVariant QGeoPositionInfoSourcePrivate::backendProperty(const QString &/*name*/) const
{
    return QVariant();
}

QHash<QString, QJsonObject> QGeoPositionInfoSourcePrivate::plugins(bool reload)
{
    static QHash<QString, QJsonObject> plugins;
    static bool alreadyDiscovered = false;

    if (reload == true)
        alreadyDiscovered = false;

    if (!alreadyDiscovered) {
        loadPluginMetadata(plugins);
        alreadyDiscovered = true;
    }
    return plugins;
}

static bool pluginComparator(const QJsonObject &p1, const QJsonObject &p2)
{
    const QString prio = QStringLiteral("Priority");
    if (p1.contains(prio) && !p2.contains(prio))
        return true;
    if (!p1.contains(prio) && p2.contains(prio))
        return false;
    if (p1.value(prio).isDouble() && !p2.value(prio).isDouble())
        return true;
    if (!p1.value(prio).isDouble() && p2.value(prio).isDouble())
        return false;
    return (p1.value(prio).toDouble() > p2.value(prio).toDouble());
}

QList<QJsonObject> QGeoPositionInfoSourcePrivate::pluginsSorted()
{
    QList<QJsonObject> list = plugins().values();
    std::stable_sort(list.begin(), list.end(), pluginComparator);
    return list;
}

void QGeoPositionInfoSourcePrivate::loadPluginMetadata(QHash<QString, QJsonObject> &plugins)
{
    QFactoryLoader *l = loader();
    QList<QJsonObject> meta = l->metaData();
    for (int i = 0; i < meta.size(); ++i) {
        QJsonObject obj = meta.at(i).value(QStringLiteral("MetaData")).toObject();
        const QString testableKey = QStringLiteral("Testable");
        if (obj.contains(testableKey) && !obj.value(testableKey).toBool()) {
            static bool inTest = qEnvironmentVariableIsSet("QT_QTESTLIB_RUNNING");
            if (inTest)
                continue;
        }
        obj.insert(QStringLiteral("index"), i);
        plugins.insertMulti(obj.value(QStringLiteral("Provider")).toString(), obj);
    }
}

/*!
    Creates a position source with the specified \a parent.
*/

QGeoPositionInfoSource::QGeoPositionInfoSource(QObject *parent)
        : QObject(parent),
        d(new QGeoPositionInfoSourcePrivate)
{
    qRegisterMetaType<QGeoPositionInfo>();
    d->interval = 0;
    d->methods = 0;
}

/*!
    Destroys the position source.
*/
QGeoPositionInfoSource::~QGeoPositionInfoSource()
{
    delete d;
}

/*!
    \property QGeoPositionInfoSource::sourceName
    \brief This property holds the unique name of the position source
           implementation in use.

    This is the same name that can be passed to createSource() in order to
    create a new instance of a particular position source implementation.
*/
QString QGeoPositionInfoSource::sourceName() const
{
    return d->metaData.value(QStringLiteral("Provider")).toString();
}

/*!
    Sets the backend-specific property named \a name to \a value.
    Returns \c true on success, \c false otherwise.
    Backend-specific properties can be used to configure the positioning subsystem behavior
    at runtime.
    Supported backend-specific properties are listed and described in
    \l {Qt Positioning plugins#Default plugins}.

    \sa backendProperty
    \since Qt 5.14
*/
bool QGeoPositionInfoSource::setBackendProperty(const QString &name, const QVariant &value)
{
    return d->setBackendProperty(name, value);
}

/*!
    Returns the value of the backend-specific property named \a name, if present.
    Otherwise, the returned value will be invalid.
    Supported backend-specific properties are listed and described in
    \l {Qt Positioning plugins#Default plugins}.

    \sa setBackendProperty
    \since Qt 5.14
*/
QVariant QGeoPositionInfoSource::backendProperty(const QString &name) const
{
    return d->backendProperty(name);
}

/*!
    \property QGeoPositionInfoSource::updateInterval
    \brief This property holds the requested interval in milliseconds between each update.

    If the update interval is not set (or is set to 0) the
    source will provide updates as often as necessary.

    If the update interval is set, the source will provide updates at an
    interval as close to the requested interval as possible. If the requested
    interval is less than the minimumUpdateInterval(),
    the minimum interval is used instead.

    Changes to the update interval will happen as soon as is practical, however the
    time the change takes may vary between implementations.  Whether or not the elapsed
    time from the previous interval is counted as part of the new interval is also
    implementation dependent.

    The default value for this property is 0.

    Note: Subclass implementations must call the base implementation of
    setUpdateInterval() so that updateInterval() returns the correct value.
*/
void QGeoPositionInfoSource::setUpdateInterval(int msec)
{
    d->interval = msec;
}

int QGeoPositionInfoSource::updateInterval() const
{
    return d->interval;
}

/*!
    Sets the preferred positioning methods for this source to \a methods.

    If \a methods includes a method that is not supported by the source, the
    unsupported method will be ignored.

    If \a methods does not include a single method available/supported by the source, the
    preferred methods will be set to the set of methods which the source has available.
    If the source has no method availabe (e.g. because its Location service is turned off
    or it does not offer a Location service), the passed \a methods are accepted as they are.

    \b {Note:} When reimplementing this method, subclasses must call the
    base method implementation to ensure preferredPositioningMethods() returns the correct value.

    \sa supportedPositioningMethods()
*/
void QGeoPositionInfoSource::setPreferredPositioningMethods(PositioningMethods methods)
{
    if (supportedPositioningMethods() != QGeoPositionInfoSource::NoPositioningMethods) {
        d->methods = methods & supportedPositioningMethods();
        if (d->methods == 0) {
            d->methods = supportedPositioningMethods();
        }
    } else { // avoid that turned of Location service blocks any changes to d->methods
        d->methods = methods;
    }
}

/*!
    Returns the positioning methods set by setPreferredPositioningMethods().
*/
QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSource::preferredPositioningMethods() const
{
    return d->methods;
}

static QGeoPositionInfoSource* createSource_real(const QJsonObject &meta, const QVariantMap &parameters, QObject *parent)
{
    QGeoPositionInfoSourcePrivate d;
    d.metaData = meta;
    d.loadPlugin();
    QGeoPositionInfoSource *s = nullptr;
    if (!parameters.isEmpty() && d.factoryV2)
        s = d.factoryV2->positionInfoSourceWithParameters(parent, parameters);
    else if (d.factory)
        s = d.factory->positionInfoSource(parent);
    if (s)
        QGeoPositionInfoSourcePrivate::get(*s)->metaData = d.metaData;

    return s;
}

/*!
    Creates and returns a position source with the given \a parent that
    reads from the system's default sources of location data, or the plugin
    with the highest available priority.

    Returns 0 if the system has no default position source, no valid plugins
    could be found or the user does not have the permission to access the current position.
*/
QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(QObject *parent)
{
    return createDefaultSource(QVariantMap(), parent);
}

/*!
    Creates and returns a position source with the given \a parent that
    reads from the system's default sources of location data, or the plugin
    with the highest available priority.

    Returns nullptr if the system has no default position source, no valid plugins
    could be found or the user does not have the permission to access the current position.

    This method passes \a parameters to the factory to configure the source.

    \since Qt 5.14
*/
QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(const QVariantMap &parameters, QObject *parent)
{
    QList<QJsonObject> plugins = QGeoPositionInfoSourcePrivate::pluginsSorted();
    foreach (const QJsonObject &obj, plugins) {
        if (obj.value(QStringLiteral("Position")).isBool()
                && obj.value(QStringLiteral("Position")).toBool()) {
            QGeoPositionInfoSource *source = createSource_real(obj, parameters, parent);
            if (source)
                return source;
        }
    }
    return nullptr;
}

/*!
    Creates and returns a position source with the given \a parent,
    by loading the plugin named \a sourceName.

    Returns 0 if the plugin cannot be found.
*/
QGeoPositionInfoSource *QGeoPositionInfoSource::createSource(const QString &sourceName, QObject *parent)
{
    return createSource(sourceName, QVariantMap(), parent);
}

/*!
    Creates and returns a position source with the given \a parent,
    by loading the plugin named \a sourceName.

    Returns nullptr if the plugin cannot be found.

    This method passes \a parameters to the factory to configure the source.

    \since Qt 5.14
*/
QGeoPositionInfoSource *QGeoPositionInfoSource::createSource(const QString &sourceName, const QVariantMap &parameters, QObject *parent)
{
    QHash<QString, QJsonObject> plugins = QGeoPositionInfoSourcePrivate::plugins();
    if (plugins.contains(sourceName))
        return createSource_real(plugins.value(sourceName), parameters, parent);
    return nullptr;
}

/*!
    Returns a list of available source plugins. This includes any default backend
    plugin for the current platform.
*/
QStringList QGeoPositionInfoSource::availableSources()
{
    QStringList plugins;
    const QHash<QString, QJsonObject> meta = QGeoPositionInfoSourcePrivate::plugins();
    for (auto it = meta.cbegin(), end = meta.cend(); it != end; ++it) {
        if (it.value().value(QStringLiteral("Position")).isBool()
                && it.value().value(QStringLiteral("Position")).toBool()) {
            plugins << it.key();
        }
    }

    return plugins;
}

QGeoPositionInfoSource::QGeoPositionInfoSource(QGeoPositionInfoSourcePrivate &dd, QObject *parent)
:   QObject(parent),
    d(&dd)
{
    qRegisterMetaType<QGeoPositionInfo>();
    d->interval = 0;
    d->methods = NoPositioningMethods;
}

/*!
    \fn QGeoPositionInfo QGeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0;

    Returns an update containing the last known position, or a null update
    if none is available.

    If \a fromSatellitePositioningMethodsOnly is true, this returns the last
    known position received from a satellite positioning method; if none
    is available, a null update is returned.
*/

/*!
    \fn virtual PositioningMethods QGeoPositionInfoSource::supportedPositioningMethods() const = 0;

    Returns the positioning methods available to this source. Availability is defined as being usable
    at the time of calling this function. Therefore user settings like turned off location service or
    limitations to Satellite-based position providers are reflected by this function. Runtime notifications
    when the status changes can be obtained via \l supportedPositioningMethodsChanged().

    Not all platforms distinguish the different positioning methods or communicate the current user
    configuration of the device. The following table provides an overview of the current platform situation:

    \table
    \header
        \li Platform
        \li Brief Description
    \row
        \li Android
        \li Individual provider status and general Location service state are known and communicated
            when location service is active.
    \row
        \li GeoClue
        \li Hardcoced to always return AllPositioningMethods.
    \row
        \li GeoClue2
        \li Individual providers are not distinguishable but disabled Location services reflected.
    \row
        \li iOS/tvOS
        \li Hardcoced to always return AllPositioningMethods.
    \row
        \li macOS
        \li Hardcoced to always return AllPositioningMethods.
    \row
        \li Windows (UWP)
        \li Individual providers are not distinguishable but disabled Location services reflected.
    \endtable

    \sa supportedPositioningMethodsChanged(), setPreferredPositioningMethods()
*/


/*!
    \property QGeoPositionInfoSource::minimumUpdateInterval
    \brief This property holds the minimum time (in milliseconds) required to retrieve a position update.

    This is the minimum value accepted by setUpdateInterval() and
    requestUpdate().
*/


/*!
    \fn virtual void QGeoPositionInfoSource::startUpdates() = 0;

    Starts emitting updates at regular intervals as specified by setUpdateInterval().

    If setUpdateInterval() has not been called, the source will emit updates
    as soon as they become available.

    An updateTimeout() signal will be emitted if this QGeoPositionInfoSource subclass determines
    that it will not be able to provide regular updates.  This could happen if a satellite fix is
    lost or if a hardware error is detected.  Position updates will recommence if the data becomes
    available later on.  The updateTimeout() signal will not be emitted again until after the
    periodic updates resume.

    On iOS, starting from version 8, Core Location framework requires additional
    entries in the application's Info.plist with keys NSLocationAlwaysUsageDescription or
    NSLocationWhenInUseUsageDescription and a string to be displayed in the authorization prompt.
    The key NSLocationWhenInUseUsageDescription is used when requesting permission
    to use location services while the app is in the foreground.
    The key NSLocationAlwaysUsageDescription is used when requesting permission
    to use location services whenever the app is running (both the foreground and the background).
    If both entries are defined, NSLocationWhenInUseUsageDescription has a priority in the
    foreground mode.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::stopUpdates() = 0;

    Stops emitting updates at regular intervals.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::requestUpdate(int timeout = 0);

    Attempts to get the current position and emit positionUpdated() with
    this information. If the current position cannot be found within the given \a timeout
    (in milliseconds) or if \a timeout is less than the value returned by
    minimumUpdateInterval(), updateTimeout() is emitted.

    If the timeout is zero, the timeout defaults to a reasonable timeout
    period as appropriate for the source.

    This does nothing if another update request is in progress. However
    it can be called even if startUpdates() has already been called and
    regular updates are in progress.

    If the source uses multiple positioning methods, it tries to get the
    current position from the most accurate positioning method within the
    given timeout.
*/

/*!
     \fn virtual QGeoPositionInfoSource::Error QGeoPositionInfoSource::error() const;

     Returns the type of error that last occurred.

*/

/*!
    \fn void QGeoPositionInfoSource::positionUpdated(const QGeoPositionInfo &update);

    If startUpdates() or requestUpdate() is called, this signal is emitted
    when an update becomes available.

    The \a update value holds the value of the new update.
*/

/*!
    \fn void QGeoPositionInfoSource::updateTimeout();

    If requestUpdate() was called, this signal will be emitted if the current position could not
    be retrieved within the specified timeout.

    If startUpdates() has been called, this signal will be emitted if this QGeoPositionInfoSource
    subclass determines that it will not be able to provide further regular updates.  This signal
    will not be emitted again until after the regular updates resume.

    While the triggering of this signal may be considered an error condition, it does not
    imply the emission of the \c error() signal. Only the emission of \c updateTimeout() is required
    to indicate a timeout.
*/

/*!
    \fn void QGeoPositionInfoSource::error(QGeoPositionInfoSource::Error positioningError)

    This signal is emitted after an error occurred. The \a positioningError
    parameter describes the type of error that occurred.

    This signal is not emitted when an updateTimeout() has occurred.

*/

/*!
    \enum QGeoPositionInfoSource::Error

    The Error enumeration represents the errors which can occur.

    \value AccessError The connection setup to the remote positioning backend failed because the
        application lacked the required privileges.
    \value ClosedError  The remote positioning backend closed the connection, which happens for example in case
        the user is switching location services to off. As soon as the location service is re-enabled
        regular updates will resume.
    \value NoError No error has occurred.
    \value UnknownSourceError An unidentified error occurred.
 */

/*!
    \fn void QGeoPositionInfoSource::supportedPositioningMethodsChanged()

    This signal is emitted when the supported positioning methods changed. The cause for a change could be
    a user turning Location services on/off or restricting Location services to certain types (e.g. GPS only).
    Note that changes to the supported positioning methods cannot be detected on all platforms.
    \l supportedPositioningMethods() provides an overview of the current platform support.

    \since Qt 5.12
*/

QT_END_NAMESPACE
