/****************************************************************************
**
** Copyright (C) 2016 Centria research and development
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNfc 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 "qnearfieldtarget_android_p.h"
#include "android/androidjninfc_p.h"
#include "qdebug.h"

#define NDEFTECHNOLOGY              QStringLiteral("android.nfc.tech.Ndef")
#define NDEFFORMATABLETECHNOLOGY    QStringLiteral("android.nfc.tech.NdefFormatable")
#define ISODEPTECHNOLOGY            QStringLiteral("android.nfc.tech.IsoDep")
#define NFCATECHNOLOGY              QStringLiteral("android.nfc.tech.NfcA")
#define NFCBTECHNOLOGY              QStringLiteral("android.nfc.tech.NfcB")
#define NFCFTECHNOLOGY              QStringLiteral("android.nfc.tech.NfcF")
#define NFCVTECHNOLOGY              QStringLiteral("android.nfc.tech.NfcV")
#define MIFARECLASSICTECHNOLOGY     QStringLiteral("android.nfc.tech.MifareClassic")
#define MIFARECULTRALIGHTTECHNOLOGY QStringLiteral("android.nfc.tech.MifareUltralight")

#define MIFARETAG   QStringLiteral("com.nxp.ndef.mifareclassic")
#define NFCTAGTYPE1 QStringLiteral("org.nfcforum.ndef.type1")
#define NFCTAGTYPE2 QStringLiteral("org.nfcforum.ndef.type2")
#define NFCTAGTYPE3 QStringLiteral("org.nfcforum.ndef.type3")
#define NFCTAGTYPE4 QStringLiteral("org.nfcforum.ndef.type4")

NearFieldTarget::NearFieldTarget(QAndroidJniObject intent, const QByteArray uid, QObject *parent) :
    QNearFieldTarget(parent),
    m_intent(intent),
    m_uid(uid),
    m_keepConnection(false)
{
    updateTechList();
    updateType();
    setupTargetCheckTimer();
}

NearFieldTarget::~NearFieldTarget()
{
    releaseIntent();
    emit targetDestroyed(m_uid);
}

QByteArray NearFieldTarget::uid() const
{
    return m_uid;
}

QNearFieldTarget::Type NearFieldTarget::type() const
{
    return m_type;
}

QNearFieldTarget::AccessMethods NearFieldTarget::accessMethods() const
{
    AccessMethods result = UnknownAccess;

    if (m_techList.contains(NDEFTECHNOLOGY)
            || m_techList.contains(NDEFFORMATABLETECHNOLOGY))
        result |= NdefAccess;

    if (m_techList.contains(ISODEPTECHNOLOGY)
            || m_techList.contains(NFCATECHNOLOGY)
            || m_techList.contains(NFCBTECHNOLOGY)
            || m_techList.contains(NFCFTECHNOLOGY)
            || m_techList.contains(NFCVTECHNOLOGY))
        result |= TagTypeSpecificAccess;

    return result;
}

bool NearFieldTarget::keepConnection() const
{
    return m_keepConnection;
}

bool NearFieldTarget::setKeepConnection(bool isPersistent)
{
    m_keepConnection = isPersistent;

    if (!m_keepConnection)
        disconnect();

    return true;
}

bool NearFieldTarget::disconnect()
{
    if (!m_tagTech.isValid())
        return false;

    bool connected = m_tagTech.callMethod<jboolean>("isConnected");
    if (catchJavaExceptions())
        return false;

    if (!connected)
        return false;

    m_tagTech.callMethod<void>("close");
    return !catchJavaExceptions();
}

bool NearFieldTarget::hasNdefMessage()
{
    return m_techList.contains(NDEFTECHNOLOGY);
}

QNearFieldTarget::RequestId NearFieldTarget::readNdefMessages()
{
    // Making sure that target has NDEF messages
    if (!hasNdefMessage())
        return QNearFieldTarget::RequestId();

    // Making sure that target is still in range
    QNearFieldTarget::RequestId requestId(new QNearFieldTarget::RequestIdPrivate);
    if (!m_intent.isValid()) {
        reportError(QNearFieldTarget::TargetOutOfRangeError, requestId);
        return requestId;
    }

    // Getting Ndef technology object
    if (!setTagTechnology({NDEFTECHNOLOGY})) {
        reportError(QNearFieldTarget::UnsupportedError, requestId);
        return requestId;
    }

    // Connect
    if (!connect()) {
        reportError(QNearFieldTarget::TargetOutOfRangeError, requestId);
        return requestId;
    }

    // Get NdefMessage object
    QAndroidJniObject ndefMessage = m_tagTech.callObjectMethod("getNdefMessage", "()Landroid/nfc/NdefMessage;");
    if (catchJavaExceptions())
        ndefMessage = QAndroidJniObject();
    if (!ndefMessage.isValid()) {
        reportError(QNearFieldTarget::NdefReadError, requestId);
        return requestId;
    }

    // Convert to byte array
    QAndroidJniObject ndefMessageBA = ndefMessage.callObjectMethod("toByteArray", "()[B");
    QByteArray ndefMessageQBA = jbyteArrayToQByteArray(ndefMessageBA.object<jbyteArray>());

    if (!m_keepConnection) {
        // Closing connection
        disconnect();   // IOException at this point does not matter anymore.
    }

    // Sending QNdefMessage, requestCompleted and exit.
    QNdefMessage qNdefMessage = QNdefMessage::fromByteArray(ndefMessageQBA);
    QMetaObject::invokeMethod(this, [this, qNdefMessage]() {
        Q_EMIT this->QNearFieldTarget::ndefMessageRead(qNdefMessage);
    }, Qt::QueuedConnection);
    QMetaObject::invokeMethod(this, [this, requestId]() {
        Q_EMIT this->requestCompleted(requestId);
    }, Qt::QueuedConnection);
    QMetaObject::invokeMethod(this, [this, qNdefMessage, requestId]() {
        //TODO This is an Android specific signal in NearFieldTarget.
        //     We need to check if it is still necessary.
        Q_EMIT this->ndefMessageRead(qNdefMessage, requestId);
    }, Qt::QueuedConnection);
    return requestId;
}

int NearFieldTarget::maxCommandLength() const
{
    QAndroidJniObject tagTech;
    if (m_techList.contains(ISODEPTECHNOLOGY))
        tagTech = getTagTechnology(ISODEPTECHNOLOGY);
    else if (m_techList.contains(NFCATECHNOLOGY))
        tagTech = getTagTechnology(NFCATECHNOLOGY);
    else if (m_techList.contains(NFCBTECHNOLOGY))
        tagTech = getTagTechnology(NFCBTECHNOLOGY);
    else if (m_techList.contains(NFCFTECHNOLOGY))
        tagTech = getTagTechnology(NFCFTECHNOLOGY);
    else if (m_techList.contains(NFCVTECHNOLOGY))
        tagTech = getTagTechnology(NFCVTECHNOLOGY);
    else
        return 0;

    int returnVal = tagTech.callMethod<jint>("getMaxTransceiveLength");
    if (catchJavaExceptions())
        return 0;

    return returnVal;
}

QNearFieldTarget::RequestId NearFieldTarget::sendCommand(const QByteArray &command)
{
    if (command.size() == 0 || command.size() > maxCommandLength()) {
        Q_EMIT QNearFieldTarget::error(QNearFieldTarget::InvalidParametersError, QNearFieldTarget::RequestId());
        return QNearFieldTarget::RequestId();
    }

    // Making sure that target has commands
    if (!(accessMethods() & TagTypeSpecificAccess))
        return QNearFieldTarget::RequestId();

    QAndroidJniEnvironment env;

    if (!setTagTechnology({ISODEPTECHNOLOGY, NFCATECHNOLOGY, NFCBTECHNOLOGY, NFCFTECHNOLOGY, NFCVTECHNOLOGY})) {
        Q_EMIT QNearFieldTarget::error(QNearFieldTarget::UnsupportedError, QNearFieldTarget::RequestId());
        return QNearFieldTarget::RequestId();
    }

    // Connecting
    QNearFieldTarget::RequestId requestId = QNearFieldTarget::RequestId(new QNearFieldTarget::RequestIdPrivate());
    if (!connect()) {
        reportError(QNearFieldTarget::TargetOutOfRangeError, requestId);
        return requestId;
    }

    // Making QByteArray
    QByteArray ba(command);
    jbyteArray jba = env->NewByteArray(ba.size());
    env->SetByteArrayRegion(jba, 0, ba.size(), reinterpret_cast<jbyte*>(ba.data()));

    // Writing
    QAndroidJniObject myNewVal = m_tagTech.callObjectMethod("transceive", "([B)[B", jba);
    if (catchJavaExceptions()) {
        reportError(QNearFieldTarget::CommandError, requestId);
        return requestId;
    }
    QByteArray result = jbyteArrayToQByteArray(myNewVal.object<jbyteArray>());
    env->DeleteLocalRef(jba);

    handleResponse(requestId, result);

    if (!m_keepConnection) {
        // Closing connection
        disconnect();   // IOException at this point does not matter anymore.
    }
    QMetaObject::invokeMethod(this, [this, requestId]() {
        Q_EMIT this->requestCompleted(requestId);
    }, Qt::QueuedConnection);

    return requestId;
}

QNearFieldTarget::RequestId NearFieldTarget::sendCommands(const QList<QByteArray> &commands)
{
    QNearFieldTarget::RequestId requestId;
    for (int i=0; i < commands.size(); i++)
        requestId = sendCommand(commands.at(i));
    return requestId;
}

QNearFieldTarget::RequestId NearFieldTarget::writeNdefMessages(const QList<QNdefMessage> &messages)
{
    if (messages.size() == 0)
        return QNearFieldTarget::RequestId();

    if (messages.size() > 1)
        qWarning("QNearFieldTarget::writeNdefMessages: Android supports writing only one NDEF message per tag.");

    QAndroidJniEnvironment env;
    const char *writeMethod;

    if (!setTagTechnology({NDEFFORMATABLETECHNOLOGY, NDEFTECHNOLOGY}))
        return QNearFieldTarget::RequestId();

    // Getting write method
    if (m_tech == NDEFFORMATABLETECHNOLOGY)
        writeMethod = "format";
    else
        writeMethod = "writeNdefMessage";

    // Connecting
    QNearFieldTarget::RequestId requestId = QNearFieldTarget::RequestId(new QNearFieldTarget::RequestIdPrivate());
    if (!connect()) {
        reportError(QNearFieldTarget::TargetOutOfRangeError, requestId);
        return requestId;
    }

    // Making NdefMessage object
    const QNdefMessage &message = messages.first();
    QByteArray ba = message.toByteArray();
    QAndroidJniObject jba = env->NewByteArray(ba.size());
    env->SetByteArrayRegion(jba.object<jbyteArray>(), 0, ba.size(), reinterpret_cast<jbyte*>(ba.data()));
    QAndroidJniObject jmessage = QAndroidJniObject("android/nfc/NdefMessage", "([B)V", jba.object<jbyteArray>());
    if (catchJavaExceptions()) {
        reportError(QNearFieldTarget::UnknownError, requestId);
        return requestId;
    }

    // Writing
    m_tagTech.callMethod<void>(writeMethod, "(Landroid/nfc/NdefMessage;)V", jmessage.object<jobject>());
    if (catchJavaExceptions()) {
        reportError(QNearFieldTarget::NdefWriteError, requestId);
        return requestId;
    }

    if (!m_keepConnection)
        disconnect();   // IOException at this point does not matter anymore.
    QMetaObject::invokeMethod(this, "ndefMessagesWritten", Qt::QueuedConnection);
    return requestId;
}

void NearFieldTarget::setIntent(QAndroidJniObject intent)
{
    if (m_intent == intent)
        return;

    releaseIntent();
    m_intent = intent;
    if (m_intent.isValid()) {
        // Updating tech list and type in case of there is another tag with same UID as one before.
        updateTechList();
        updateType();
        m_targetCheckTimer->start();
    }
}

void NearFieldTarget::checkIsTargetLost()
{
    if (!m_intent.isValid() || !setTagTechnology(m_techList)) {
        handleTargetLost();
        return;
    }

    bool connected = m_tagTech.callMethod<jboolean>("isConnected");
    if (catchJavaExceptions()) {
        handleTargetLost();
        return;
    }

    if (connected)
        return;

    m_tagTech.callMethod<void>("connect");
    if (catchJavaExceptions(false)) {
        handleTargetLost();
        return;
    }
    m_tagTech.callMethod<void>("close");
    if (catchJavaExceptions(false))
        handleTargetLost();
}

void NearFieldTarget::releaseIntent()
{
    m_targetCheckTimer->stop();

    m_intent = QAndroidJniObject();
}

void NearFieldTarget::updateTechList()
{
    if (!m_intent.isValid())
        return;

    // Getting tech list
    QAndroidJniEnvironment env;
    QAndroidJniObject tag = AndroidNfc::getTag(m_intent);
    Q_ASSERT_X(tag.isValid(), "updateTechList", "could not get Tag object");

    QAndroidJniObject techListArray = tag.callObjectMethod("getTechList", "()[Ljava/lang/String;");
    if (!techListArray.isValid()) {
        handleTargetLost();
        return;
    }

    // Converting tech list array to QStringList.
    m_techList.clear();
    jsize techCount = env->GetArrayLength(techListArray.object<jobjectArray>());
    for (jsize i = 0; i < techCount; ++i) {
        QAndroidJniObject tech = env->GetObjectArrayElement(techListArray.object<jobjectArray>(), i);
        m_techList.append(tech.callObjectMethod<jstring>("toString").toString());
    }
}

void NearFieldTarget::updateType()
{
    m_type = getTagType();
}

QNearFieldTarget::Type NearFieldTarget::getTagType() const
{
    QAndroidJniEnvironment env;

    if (m_techList.contains(NDEFTECHNOLOGY)) {
        QAndroidJniObject ndef = getTagTechnology(NDEFTECHNOLOGY);
        QString qtype = ndef.callObjectMethod("getType", "()Ljava/lang/String;").toString();

        if (qtype.compare(MIFARETAG) == 0)
            return MifareTag;
        if (qtype.compare(NFCTAGTYPE1) == 0)
            return NfcTagType1;
        if (qtype.compare(NFCTAGTYPE2) == 0)
            return NfcTagType2;
        if (qtype.compare(NFCTAGTYPE3) == 0)
            return NfcTagType3;
        if (qtype.compare(NFCTAGTYPE4) == 0)
            return NfcTagType4;
        return ProprietaryTag;
    } else if (m_techList.contains(NFCATECHNOLOGY)) {
        if (m_techList.contains(MIFARECLASSICTECHNOLOGY))
            return MifareTag;

        // Checking ATQA/SENS_RES
        // xxx0 0000  xxxx xxxx: Identifies tag Type 1 platform
        QAndroidJniObject nfca = getTagTechnology(NFCATECHNOLOGY);
        QAndroidJniObject atqaBA = nfca.callObjectMethod("getAtqa", "()[B");
        QByteArray atqaQBA = jbyteArrayToQByteArray(atqaBA.object<jbyteArray>());
        if (atqaQBA.isEmpty())
            return ProprietaryTag;
        if ((atqaQBA[0] & 0x1F) == 0x00)
            return NfcTagType1;

        // Checking SAK/SEL_RES
        // xxxx xxxx  x00x x0xx: Identifies tag Type 2 platform
        // xxxx xxxx  x01x x0xx: Identifies tag Type 4 platform
        jshort sakS = nfca.callMethod<jshort>("getSak");
        if ((sakS & 0x0064) == 0x0000)
            return NfcTagType2;
        else if ((sakS & 0x0064) == 0x0020)
            return NfcTagType4;
        return ProprietaryTag;
    } else if (m_techList.contains(NFCBTECHNOLOGY)) {
        return NfcTagType4;
    } else if (m_techList.contains(NFCFTECHNOLOGY)) {
        return NfcTagType3;
    }

    return ProprietaryTag;
}

void NearFieldTarget::setupTargetCheckTimer()
{
    m_targetCheckTimer = new QTimer(this);
    m_targetCheckTimer->setInterval(1000);
    QObject::connect(m_targetCheckTimer, &QTimer::timeout, this, &NearFieldTarget::checkIsTargetLost);
    m_targetCheckTimer->start();
}

void NearFieldTarget::handleTargetLost()
{
    releaseIntent();
    emit targetLost(this);
}

QAndroidJniObject NearFieldTarget::getTagTechnology(const QString &tech) const
{
    QString techClass(tech);
    techClass.replace(QLatin1Char('.'), QLatin1Char('/'));

    // Getting requested technology
    QAndroidJniObject tag = AndroidNfc::getTag(m_intent);
    Q_ASSERT_X(tag.isValid(), "getTagTechnology", "could not get Tag object");

    const QString sig = QString::fromUtf8("(Landroid/nfc/Tag;)L%1;");
    QAndroidJniObject tagTech = QAndroidJniObject::callStaticObjectMethod(techClass.toUtf8().constData(), "get",
            sig.arg(techClass).toUtf8().constData(), tag.object<jobject>());

    return tagTech;
}

bool NearFieldTarget::setTagTechnology(const QStringList &techList)
{
    for (const QString &tech : techList) {
        if (m_techList.contains(tech)) {
            if (m_tech == tech) {
                return true;
            }
            m_tech = tech;
            m_tagTech = getTagTechnology(tech);
            return m_tagTech.isValid();
        }
    }

    return false;
}

bool NearFieldTarget::connect()
{
    if (!m_tagTech.isValid())
        return false;

    bool connected = m_tagTech.callMethod<jboolean>("isConnected");
    if (catchJavaExceptions())
        return false;

    if (connected)
        return true;

    m_tagTech.callMethod<void>("connect");
    return !catchJavaExceptions();
}

QByteArray NearFieldTarget::jbyteArrayToQByteArray(const jbyteArray &byteArray) const
{
    QAndroidJniEnvironment env;
    QByteArray resultArray;
    jsize len = env->GetArrayLength(byteArray);
    resultArray.resize(len);
    env->GetByteArrayRegion(byteArray, 0, len, reinterpret_cast<jbyte*>(resultArray.data()));
    return resultArray;
}

bool NearFieldTarget::catchJavaExceptions(bool verbose) const
{
    QAndroidJniEnvironment env;
    if (env->ExceptionCheck()) {
        if (verbose)
            env->ExceptionDescribe();
        env->ExceptionClear();
        return true;
    }
    return false;
}
