/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth 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 "lowenergynotificationhub_p.h"

#include <QtCore/QHash>
#include <QtCore/QLoggingCategory>
#include <QtCore/QRandomGenerator>
#include <QtAndroidExtras/QAndroidJniEnvironment>

QT_BEGIN_NAMESPACE

typedef QHash<long, LowEnergyNotificationHub*> HubMapType;
Q_GLOBAL_STATIC(HubMapType, hubMap)

QReadWriteLock LowEnergyNotificationHub::lock;

Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)

LowEnergyNotificationHub::LowEnergyNotificationHub(const QBluetoothAddress &remote,
                                                   bool isPeripheral, QObject *parent)
    :   QObject(parent), javaToCtoken(0)
{
    QAndroidJniEnvironment env;

    if (isPeripheral) {
        qCDebug(QT_BT_ANDROID) << "Creating Android Peripheral/Server support for BTLE";
        jBluetoothLe = QAndroidJniObject("org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer",
                                         "(Landroid/content/Context;)V", QtAndroidPrivate::context());
    } else {
        qCDebug(QT_BT_ANDROID) << "Creating Android Central/Client support for BTLE";
        const QAndroidJniObject address =
            QAndroidJniObject::fromString(remote.toString());
        jBluetoothLe = QAndroidJniObject("org/qtproject/qt5/android/bluetooth/QtBluetoothLE",
                                     "(Ljava/lang/String;Landroid/content/Context;)V",
                                     address.object<jstring>(),
                                     QtAndroidPrivate::context());
    }

    if (env->ExceptionCheck() || !jBluetoothLe.isValid()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
        jBluetoothLe = QAndroidJniObject();
        return;
    }

    // register C++ class pointer in Java
    lock.lockForWrite();

    while (true) {
        javaToCtoken = QRandomGenerator::global()->generate();
        if (!hubMap()->contains(javaToCtoken))
            break;
    }

    hubMap()->insert(javaToCtoken, this);
    lock.unlock();

    jBluetoothLe.setField<jlong>("qtObject", javaToCtoken);
}

LowEnergyNotificationHub::~LowEnergyNotificationHub()
{
    lock.lockForWrite();
    hubMap()->remove(javaToCtoken);
    lock.unlock();
}

// runs in Java thread
void LowEnergyNotificationHub::lowEnergy_connectionChange(JNIEnv *, jobject, jlong qtObject, jint errorCode, jint newState)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QMetaObject::invokeMethod(hub, "connectionUpdated", Qt::QueuedConnection,
                              Q_ARG(QLowEnergyController::ControllerState,
                                    (QLowEnergyController::ControllerState)newState),
                              Q_ARG(QLowEnergyController::Error,
                                    (QLowEnergyController::Error)errorCode));
}

void LowEnergyNotificationHub::lowEnergy_servicesDiscovered(
        JNIEnv *, jobject, jlong qtObject, jint errorCode, jobject uuidList)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    const QString uuids = QAndroidJniObject(uuidList).toString();
    QMetaObject::invokeMethod(hub, "servicesDiscovered", Qt::QueuedConnection,
                              Q_ARG(QLowEnergyController::Error,
                                    (QLowEnergyController::Error)errorCode),
                              Q_ARG(QString, uuids));
}

void LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered(
        JNIEnv *, jobject, jlong qtObject, jobject uuid, jint startHandle,
        jint endHandle)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    const QString serviceUuid = QAndroidJniObject(uuid).toString();
    QMetaObject::invokeMethod(hub, "serviceDetailsDiscoveryFinished",
                              Qt::QueuedConnection,
                              Q_ARG(QString, serviceUuid),
                              Q_ARG(int, startHandle),
                              Q_ARG(int, endHandle));
}

void LowEnergyNotificationHub::lowEnergy_characteristicRead(
        JNIEnv *env, jobject, jlong qtObject, jobject sUuid, jint handle,
        jobject cUuid, jint properties, jbyteArray data)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    const QBluetoothUuid serviceUuid(QAndroidJniObject(sUuid).toString());
    if (serviceUuid.isNull())
        return;

    const QBluetoothUuid charUuid(QAndroidJniObject(cUuid).toString());
    if (charUuid.isNull())
        return;

    QByteArray payload;
    if (data) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(data);
        payload.resize(length);
        env->GetByteArrayRegion(data, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "characteristicRead", Qt::QueuedConnection,
                              Q_ARG(QBluetoothUuid, serviceUuid),
                              Q_ARG(int, handle),
                              Q_ARG(QBluetoothUuid, charUuid),
                              Q_ARG(int, properties),
                              Q_ARG(QByteArray, payload));

}

void LowEnergyNotificationHub::lowEnergy_descriptorRead(
        JNIEnv *env, jobject, jlong qtObject, jobject sUuid, jobject cUuid,
        jint handle, jobject dUuid, jbyteArray data)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    const QBluetoothUuid serviceUuid(QAndroidJniObject(sUuid).toString());
    if (serviceUuid.isNull())
        return;

    const QBluetoothUuid charUuid(QAndroidJniObject(cUuid).toString());
    const QBluetoothUuid descUuid(QAndroidJniObject(dUuid).toString());
    if (charUuid.isNull() || descUuid.isNull())
        return;

    QByteArray payload;
    if (data) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(data);
        payload.resize(length);
        env->GetByteArrayRegion(data, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "descriptorRead", Qt::QueuedConnection,
                              Q_ARG(QBluetoothUuid, serviceUuid),
                              Q_ARG(QBluetoothUuid, charUuid),
                              Q_ARG(int, handle),
                              Q_ARG(QBluetoothUuid, descUuid),
                              Q_ARG(QByteArray, payload));
}

void LowEnergyNotificationHub::lowEnergy_characteristicWritten(
        JNIEnv *env, jobject, jlong qtObject, jint charHandle,
        jbyteArray data, jint errorCode)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QByteArray payload;
    if (data) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(data);
        payload.resize(length);
        env->GetByteArrayRegion(data, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "characteristicWritten", Qt::QueuedConnection,
                              Q_ARG(int, charHandle),
                              Q_ARG(QByteArray, payload),
                              Q_ARG(QLowEnergyService::ServiceError,
                                    (QLowEnergyService::ServiceError)errorCode));
}

void LowEnergyNotificationHub::lowEnergy_descriptorWritten(
        JNIEnv *env, jobject, jlong qtObject, jint descHandle,
        jbyteArray data, jint errorCode)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QByteArray payload;
    if (data) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(data);
        payload.resize(length);
        env->GetByteArrayRegion(data, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "descriptorWritten", Qt::QueuedConnection,
                              Q_ARG(int, descHandle),
                              Q_ARG(QByteArray, payload),
                              Q_ARG(QLowEnergyService::ServiceError,
                                    (QLowEnergyService::ServiceError)errorCode));
}

void LowEnergyNotificationHub::lowEnergy_serverDescriptorWritten(
        JNIEnv *env, jobject, jlong qtObject, jobject descriptor, jbyteArray newValue)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QByteArray payload;
    if (newValue) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(newValue);
        payload.resize(length);
        env->GetByteArrayRegion(newValue, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "serverDescriptorWritten", Qt::QueuedConnection,
                              Q_ARG(QAndroidJniObject, descriptor),
                              Q_ARG(QByteArray, payload));
}

void LowEnergyNotificationHub::lowEnergy_characteristicChanged(
        JNIEnv *env, jobject, jlong qtObject, jint charHandle, jbyteArray data)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QByteArray payload;
    if (data) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(data);
        payload.resize(length);
        env->GetByteArrayRegion(data, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "characteristicChanged", Qt::QueuedConnection,
                              Q_ARG(int, charHandle), Q_ARG(QByteArray, payload));
}

void LowEnergyNotificationHub::lowEnergy_serverCharacteristicChanged(
        JNIEnv *env, jobject, jlong qtObject, jobject characteristic, jbyteArray newValue)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QByteArray payload;
    if (newValue) { //empty Java byte array is 0x0
        jsize length = env->GetArrayLength(newValue);
        payload.resize(length);
        env->GetByteArrayRegion(newValue, 0, length,
                                reinterpret_cast<signed char*>(payload.data()));
    }

    QMetaObject::invokeMethod(hub, "serverCharacteristicChanged", Qt::QueuedConnection,
                              Q_ARG(QAndroidJniObject, characteristic),
                              Q_ARG(QByteArray, payload));
}

void LowEnergyNotificationHub::lowEnergy_serviceError(
        JNIEnv *, jobject, jlong qtObject, jint attributeHandle, int errorCode)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QMetaObject::invokeMethod(hub, "serviceError", Qt::QueuedConnection,
                              Q_ARG(int, attributeHandle),
                              Q_ARG(QLowEnergyService::ServiceError,
                                    (QLowEnergyService::ServiceError)errorCode));
}

void LowEnergyNotificationHub::lowEnergy_advertisementError(
        JNIEnv *, jobject, jlong qtObject, jint status)
{
    lock.lockForRead();
    LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
    lock.unlock();
    if (!hub)
        return;

    QMetaObject::invokeMethod(hub, "advertisementError", Qt::QueuedConnection,
                              Q_ARG(int, status));
}

QT_END_NAMESPACE
