/***************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** 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 "qlowenergycharacteristic.h"
#include "qlowenergyserviceprivate_p.h"
#include <QHash>

QT_BEGIN_NAMESPACE

/*!
    \class QLowEnergyCharacteristic
    \inmodule QtBluetooth
    \brief The QLowEnergyCharacteristic class stores information about a Bluetooth
    Low Energy service characteristic.

    \since 5.4

    QLowEnergyCharacteristic provides information about a Bluetooth Low Energy
    service characteristic's \l name(), \l uuid(), \l value(), \l properties(),
    \l handle() and \l descriptors(). To obtain the characteristic's specification
    and information, it is necessary to connect to the device using the
    \l QLowEnergyService and \l QLowEnergyController classes.

    The characteristic value may be written via the \l QLowEnergyService instance
    that manages the service to which this characteristic belongs. The
    \l {QLowEnergyService::writeCharacteristic()} function writes the new value.
    The \l {QLowEnergyService::characteristicWritten()} signal is emitted upon success.
    The \l value() of this object is automatically updated accordingly.

    Characteristics may contain none, one or more descriptors. They can be individually
    retrieved using the \l descriptor() function. The \l descriptors() function returns
    all descriptors as a list. The general purpose of a descriptor is to add contextual
    information to the characteristic. For example, the descriptor might provide
    format or range information specifying how the characteristic's value is to be\
    interpreted.

    \sa QLowEnergyService, QLowEnergyDescriptor
*/

/*!
    \enum QLowEnergyCharacteristic::PropertyType

    This enum describes the properties of a characteristic.

    \value Unknown                  The type is not known.
    \value Broadcasting             Allow for the broadcasting of Generic Attributes (GATT) characteristic values.
    \value Read                     Allow the characteristic values to be read.
    \value WriteNoResponse          Allow characteristic values without responses to be written.
    \value Write                    Allow for characteristic values to be written.
    \value Notify                   Permits notification of characteristic values.
    \value Indicate                 Permits indications of characteristic values.
    \value WriteSigned              Permits signed writes of the GATT characteristic values.
    \value ExtendedProperty         Additional characteristic properties are defined in the characteristic's
                                    extended properties descriptor.

    \sa properties()
*/

struct QLowEnergyCharacteristicPrivate
{
    QLowEnergyHandle handle;
};

/*!
    Construct a new QLowEnergyCharacteristic. A default-constructed instance of
    this class is always invalid.

    \sa isValid()
*/
QLowEnergyCharacteristic::QLowEnergyCharacteristic():
    d_ptr(nullptr)
{

}

/*!
    Construct a new QLowEnergyCharacteristic that is a copy of \a other.

    The two copies continue to share the same underlying data which does not detach
    upon write.
*/
QLowEnergyCharacteristic::QLowEnergyCharacteristic(const QLowEnergyCharacteristic &other):
    d_ptr(other.d_ptr)
{
    if (other.data) {
        data = new QLowEnergyCharacteristicPrivate();
        data->handle = other.data->handle;
    }
}

/*!
    \internal
*/
QLowEnergyCharacteristic::QLowEnergyCharacteristic(
        QSharedPointer<QLowEnergyServicePrivate> p, QLowEnergyHandle handle):
    d_ptr(p)
{
    data = new QLowEnergyCharacteristicPrivate();
    data->handle = handle;
}

/*!
    Destroys the QLowEnergyCharacteristic object.
*/
QLowEnergyCharacteristic::~QLowEnergyCharacteristic()
{
    delete data;
}

/*!
    Returns the human-readable name of the characteristic.

    The name is based on the characteristic's \l uuid() which must have been
    standardized. The complete list of characteristic types can be found
    under \l {https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx}{Bluetooth.org Characteristics}.

    The returned string is empty if the \l uuid() is unknown.

    \sa QBluetoothUuid::characteristicToString()
*/
QString QLowEnergyCharacteristic::name() const
{
    return QBluetoothUuid::characteristicToString(
                static_cast<QBluetoothUuid::CharacteristicType>(uuid().toUInt16()));
}

/*!
    Returns the UUID of the characteristic if \l isValid() returns \c true; otherwise a
    \l {QUuid::isNull()}{null} UUID.
*/
QBluetoothUuid QLowEnergyCharacteristic::uuid() const
{
    if (d_ptr.isNull() || !data
        || !d_ptr->characteristicList.contains(data->handle))
        return QBluetoothUuid();

    return d_ptr->characteristicList[data->handle].uuid;
}

/*!
    Returns the properties of the characteristic.

    The properties define the access permissions for the characteristic.
*/
QLowEnergyCharacteristic::PropertyTypes QLowEnergyCharacteristic::properties() const
{
    if (d_ptr.isNull() || !data
        || !d_ptr->characteristicList.contains(data->handle))
        return QLowEnergyCharacteristic::Unknown;

    return d_ptr->characteristicList[data->handle].properties;
}

/*!
    Returns the cached value of the characteristic.

    If the characteristic's \l properties() permit writing of new values,
    the value can be updated using \l QLowEnergyService::writeCharacteristic().

    The cache is updated during the associated service's
    \l {QLowEnergyService::discoverDetails()} {detail discovery}, a successful
    \l {QLowEnergyService::readCharacteristic()}{read}/\l {QLowEnergyService::writeCharacteristic()}{write}
    operation or when an update notification is received.

    The returned \l QByteArray always remains empty if the characteristic does not
    have the \l {QLowEnergyCharacteristic::Read}{read permission}. In such cases only
    the \l QLowEnergyService::characteristicChanged() or
    \l QLowEnergyService::characteristicWritten() may provice information about the
    value of this characteristic.
*/
QByteArray QLowEnergyCharacteristic::value() const
{
    if (d_ptr.isNull() || !data
        || !d_ptr->characteristicList.contains(data->handle))
        return QByteArray();

    return d_ptr->characteristicList[data->handle].value;
}

/*!
    Returns the handle of the characteristic's value attribute;
    or \c 0 if the handle cannot be accessed on the platform or
    if the characteristic is invalid.

    \note On \macos and iOS handles can differ from 0, but these
    values have no special meaning outside of internal/private API.
*/
QLowEnergyHandle QLowEnergyCharacteristic::handle() const
{
    if (d_ptr.isNull() || !data
        || !d_ptr->characteristicList.contains(data->handle))
        return 0;

    return d_ptr->characteristicList[data->handle].valueHandle;
}

/*!
    Makes a copy of \a other and assigns it to this \l QLowEnergyCharacteristic object.
    The two copies continue to share the same service and controller details.
*/
QLowEnergyCharacteristic &QLowEnergyCharacteristic::operator=(const QLowEnergyCharacteristic &other)
{
    d_ptr = other.d_ptr;

    if (!other.data) {
        if (data) {
            delete data;
            data = nullptr;
        }
    } else {
        if (!data)
            data = new QLowEnergyCharacteristicPrivate();

        data->handle = other.data->handle;
    }
    return *this;
}

/*!
    Returns \c true if \a other is equal to this QLowEnergyCharacteristic; otherwise \c false.

    Two \l QLowEnergyCharacteristic instances are considered to be equal if they refer to
    the same characteristic on the same remote Bluetooth Low Energy device or both instances
    have been default-constructed.
 */
bool QLowEnergyCharacteristic::operator==(const QLowEnergyCharacteristic &other) const
{
    if (d_ptr != other.d_ptr)
        return false;

    if ((data && !other.data) || (!data && other.data))
        return false;

    if (!data)
        return true;

    if (data->handle != other.data->handle)
        return false;

    return true;
}

/*!
    Returns \c true if \a other is not equal to this QLowEnergyCharacteristic; otherwise \c false.

    Two QLowEnergyCharcteristic instances are considered to be equal if they refer to
    the same characteristic on the same remote Bluetooth Low Energy device or both instances
    have been default-constructed.
 */

bool QLowEnergyCharacteristic::operator!=(const QLowEnergyCharacteristic &other) const
{
    return !(*this == other);
}

/*!
    Returns \c true if the QLowEnergyCharacteristic object is valid, otherwise returns \c false.

    An invalid characteristic object is not associated with any service (default-constructed)
    or the associated service is no longer valid due to a disconnect from
    the underlying Bluetooth Low Energy device, for example. Once the object is invalid
    it cannot become valid anymore.

    \note If a \l QLowEnergyCharacteristic instance turns invalid due to a disconnect
    from the underlying device, the information encapsulated by the current
    instance remains as it was at the time of the disconnect. Therefore it can be
    retrieved after the disconnect event.
*/
bool QLowEnergyCharacteristic::isValid() const
{
    if (d_ptr.isNull() || !data)
        return false;

    if (d_ptr->state == QLowEnergyService::InvalidService)
        return false;

    return true;
}

/*!
    \internal

    Returns the handle of the characteristic or
    \c 0 if the handle cannot be accessed on the platform or if the
    characteristic is invalid.

    \note On \macos and iOS handles can differ from 0, but these
    values have no special meaning outside of internal/private API.

    \sa isValid()
 */
QLowEnergyHandle QLowEnergyCharacteristic::attributeHandle() const
{
    if (d_ptr.isNull() || !data)
        return 0;

    return data->handle;
}


/*!
    Returns the descriptor for \a uuid or an invalid \c QLowEnergyDescriptor instance.

    \sa descriptors()
*/
QLowEnergyDescriptor QLowEnergyCharacteristic::descriptor(const QBluetoothUuid &uuid) const
{
    if (d_ptr.isNull() || !data)
        return QLowEnergyDescriptor();

    CharacteristicDataMap::const_iterator charIt = d_ptr->characteristicList.constFind(data->handle);
    if (charIt != d_ptr->characteristicList.constEnd()) {
        const QLowEnergyServicePrivate::CharData &charDetails = charIt.value();

        DescriptorDataMap::const_iterator descIt = charDetails.descriptorList.constBegin();
        for ( ; descIt != charDetails.descriptorList.constEnd(); ++descIt) {
            const QLowEnergyHandle descHandle = descIt.key();
            const QLowEnergyServicePrivate::DescData &descDetails = descIt.value();

            if (descDetails.uuid == uuid)
                return QLowEnergyDescriptor(d_ptr, data->handle, descHandle);
        }
    }

    return QLowEnergyDescriptor();
}

/*!
    Returns the list of descriptors belonging to this characteristic; otherwise
    an empty list.

    \sa descriptor()
*/
QList<QLowEnergyDescriptor> QLowEnergyCharacteristic::descriptors() const
{
    QList<QLowEnergyDescriptor> result;

    if (d_ptr.isNull() || !data
                       || !d_ptr->characteristicList.contains(data->handle))
        return result;

    QList<QLowEnergyHandle> descriptorKeys = d_ptr->characteristicList[data->handle].
                                                    descriptorList.keys();

    std::sort(descriptorKeys.begin(), descriptorKeys.end());

    for (const QLowEnergyHandle descHandle : qAsConst(descriptorKeys)) {
        QLowEnergyDescriptor descriptor(d_ptr, data->handle, descHandle);
        result.append(descriptor);
    }

    return result;
}

QT_END_NAMESPACE
