/***************************************************************************
**
** 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 <QtCore/QLoggingCategory>
#include "qbluetoothserver.h"
#include "qbluetoothserver_p.h"
#include "qbluetoothsocket.h"
#include "qbluetoothsocket_android_p.h"
#include "qbluetoothlocaldevice.h"
#include "android/serveracceptancethread_p.h"

#include <QCoreApplication>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)

QHash<QBluetoothServerPrivate*, int> __fakeServerPorts;

QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType,
                                                 QBluetoothServer *parent)
    : socket(0),maxPendingConnections(1), securityFlags(QBluetooth::NoSecurity), serverType(sType),
      m_lastError(QBluetoothServer::NoError), q_ptr(parent)
{
    thread = new ServerAcceptanceThread();
    thread->setMaxPendingConnections(maxPendingConnections);
}

QBluetoothServerPrivate::~QBluetoothServerPrivate()
{
    Q_Q(QBluetoothServer);
    if (isListening())
        q->close();

    __fakeServerPorts.remove(this);

    thread->deleteLater();
    thread = nullptr;
}

bool QBluetoothServerPrivate::initiateActiveListening(
        const QBluetoothUuid& uuid, const QString &serviceName)
{
    qCDebug(QT_BT_ANDROID) << "Initiate active listening" << uuid.toString() << serviceName;

    if (uuid.isNull() || serviceName.isEmpty())
        return false;

    //no change of SP profile details -> do nothing
    if (uuid == m_uuid && serviceName == m_serviceName && thread->isRunning())
        return true;

    m_uuid = uuid;
    m_serviceName = serviceName;
    thread->setServiceDetails(m_uuid, m_serviceName, securityFlags);

    thread->run();
    if (!thread->isRunning())
        return false;

    return true;
}

bool QBluetoothServerPrivate::deactivateActiveListening()
{
    if (isListening()) {
        //suppress last error signal due to intended closure
        thread->disconnect();
        thread->stop();
    }
    return true;
}

bool QBluetoothServerPrivate::isListening() const
{
    return __fakeServerPorts.contains(const_cast<QBluetoothServerPrivate *>(this));
}

void QBluetoothServer::close()
{
    Q_D(QBluetoothServer);

    __fakeServerPorts.remove(d);
    if (d->thread->isRunning()) {
        //suppress last error signal due to intended closure
        d->thread->disconnect();
        d->thread->stop();
    }
}

bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 port)
{
    Q_D(QBluetoothServer);
    if (serverType() != QBluetoothServiceInfo::RfcommProtocol) {
        d->m_lastError = UnsupportedProtocolError;
        emit error(d->m_lastError);
        return false;
    }

    const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
    if (!localDevices.count()) {
        qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
        d->m_lastError = QBluetoothServer::UnknownError;
        emit error(d->m_lastError);
        return false; //no Bluetooth device
    }

    if (!localAdapter.isNull()) {
        bool found = false;
        for (const QBluetoothHostInfo &hostInfo : localDevices) {
            if (hostInfo.address() == localAdapter) {
                found = true;
                break;
            }
        }

        if (!found) {
            qCWarning(QT_BT_ANDROID) << localAdapter.toString() << "is not a valid local Bt adapter";
            return false;
        }
    }

    if (d->isListening())
        return false;

    //check Bluetooth is available and online
    QAndroidJniObject btAdapter = QAndroidJniObject::callStaticObjectMethod(
                                        "android/bluetooth/BluetoothAdapter",
                                        "getDefaultAdapter",
                                        "()Landroid/bluetooth/BluetoothAdapter;");
    if (!btAdapter.isValid()) {
        qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
        d->m_lastError = QBluetoothServer::UnknownError;
        emit error(d->m_lastError);
        return false;
    }

    const int state = btAdapter.callMethod<jint>("getState");
    if (state != 12 ) { //BluetoothAdapter.STATE_ON
        d->m_lastError = QBluetoothServer::PoweredOffError;
        emit error(d->m_lastError);
        qCWarning(QT_BT_ANDROID) << "Bluetooth device is powered off";
        return false;
    }

    //We can not register an actual Rfcomm port, because the platform does not allow it
    //but we need a way to associate a server with a service
    if (port == 0) { //Try to assign a non taken port id
        for (int i=1; ; i++){
            if (__fakeServerPorts.key(i) == 0) {
                port = i;
                break;
            }
        }
    }

    if (__fakeServerPorts.key(port) == 0) {
        __fakeServerPorts[d] = port;

        qCDebug(QT_BT_ANDROID) << "Port" << port << "registered";
    } else {
        qCWarning(QT_BT_ANDROID) << "server with port" << port << "already registered or port invalid";
        d->m_lastError = ServiceAlreadyRegisteredError;
        emit error(d->m_lastError);
        return false;
    }

    connect(d->thread, SIGNAL(newConnection()),
            this, SIGNAL(newConnection()));
    connect(d->thread, SIGNAL(error(QBluetoothServer::Error)),
            this, SIGNAL(error(QBluetoothServer::Error)), Qt::QueuedConnection);

    return true;
}

void QBluetoothServer::setMaxPendingConnections(int numConnections)
{
    Q_D(QBluetoothServer);
    d->maxPendingConnections = numConnections;
    d->thread->setMaxPendingConnections(numConnections);
}

QBluetoothAddress QBluetoothServer::serverAddress() const
{
    //Android only supports one local adapter
    QList<QBluetoothHostInfo> hosts = QBluetoothLocalDevice::allDevices();
    Q_ASSERT(hosts.count() <= 1);

    if (hosts.isEmpty())
        return QBluetoothAddress();
    else
        return hosts.at(0).address();
}

quint16 QBluetoothServer::serverPort() const
{
    //We return the fake port
    Q_D(const QBluetoothServer);
    return __fakeServerPorts.value((QBluetoothServerPrivate*)d, 0);
}

bool QBluetoothServer::hasPendingConnections() const
{
    Q_D(const QBluetoothServer);

    return d->thread->hasPendingConnections();
}

QBluetoothSocket *QBluetoothServer::nextPendingConnection()
{
    Q_D(const QBluetoothServer);

    QAndroidJniObject socket = d->thread->nextPendingConnection();
    if (!socket.isValid())
        return 0;


    QBluetoothSocket *newSocket = new QBluetoothSocket();
    bool success = newSocket->d_ptr->setSocketDescriptor(socket, d->serverType);
    if (!success) {
        delete newSocket;
        newSocket = nullptr;
    }

    return newSocket;
}

void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
{
    Q_D(QBluetoothServer);
    d->securityFlags = security;
}

QBluetooth::SecurityFlags QBluetoothServer::securityFlags() const
{
    Q_D(const QBluetoothServer);
    return d->securityFlags;
}

QT_END_NAMESPACE

