/****************************************************************************
**
** 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);

    setResponseForRequest(requestId, result, false);

    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;
}
