/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>

#include "errno.h"
#include "com_android_nfc.h"
#include "com_android_nfc_list.h"
#include "phLibNfcStatus.h"

/*
 * JNI Initialization
 */
jint JNI_OnLoad(JavaVM *jvm, void *reserved)
{
   JNIEnv *e;

   LOGD("NFC Service : loading JNI\n");

   // Check JNI version
   if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6))
      return JNI_ERR;

   android::vm = jvm;

   if (android::register_com_android_nfc_NativeNfcManager(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeNfcTag(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeP2pDevice(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeLlcpSocket(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeLlcpConnectionlessSocket(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeLlcpServiceSocket(e) == -1)
      return JNI_ERR;
   if (android::register_com_android_nfc_NativeNfcSecureElement(e) == -1)
      return JNI_ERR;

   return JNI_VERSION_1_6;
}

namespace android {

extern struct nfc_jni_native_data *exported_nat;

JavaVM *vm;

/*
 * JNI Utils
 */
JNIEnv *nfc_get_env()
{
    JNIEnv *e;
    if (vm->GetEnv((void **)&e, JNI_VERSION_1_6) != JNI_OK) {
        LOGE("Current thread is not attached to VM");
        abort();
    }
    return e;
}

bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext)
{
   /* Create semaphore */
   if(sem_init(&pCallbackData->sem, 0, 0) == -1)
   {
      LOGE("Semaphore creation failed (errno=0x%08x)", errno);
      return false;
   }

   /* Set default status value */
   pCallbackData->status = NFCSTATUS_FAILED;

   /* Copy the context */
   pCallbackData->pContext = pContext;

   /* Add to active semaphore list */
   if (!listAdd(&nfc_jni_get_monitor()->sem_list, pCallbackData))
   {
      LOGE("Failed to add the semaphore to the list");
   }

   return true;
}

void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData)
{
   /* Destroy semaphore */
   if (sem_destroy(&pCallbackData->sem))
   {
      LOGE("Failed to destroy semaphore (errno=0x%08x)", errno);
   }

   /* Remove from active semaphore list */
   if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData))
   {
      LOGE("Failed to remove semaphore from the list");
   }

}

void nfc_cb_data_releaseAll()
{
   nfc_jni_callback_data* pCallbackData;

   while (listGetAndRemoveNext(&nfc_jni_get_monitor()->sem_list, (void**)&pCallbackData))
   {
      pCallbackData->status = NFCSTATUS_FAILED;
      sem_post(&pCallbackData->sem);
   }
}

int nfc_jni_cache_object(JNIEnv *e, const char *clsname,
   jobject *cached_obj)
{
   jclass cls;
   jobject obj;
   jmethodID ctor;

   cls = e->FindClass(clsname);
   if(cls == NULL)
   {
      return -1;
      LOGD("Find class error\n");
   }


   ctor = e->GetMethodID(cls, "<init>", "()V");

   obj = e->NewObject(cls, ctor);
   if(obj == NULL)
   {
      return -1;
      LOGD("Create object error\n");
   }

   *cached_obj = e->NewGlobalRef(obj);
   if(*cached_obj == NULL)
   {
      e->DeleteLocalRef(obj);
      LOGD("Global ref error\n");
      return -1;
   }

   e->DeleteLocalRef(obj);

   return 0;
}


struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;

   /* Retrieve native structure address */
   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mNative", "I");
   return (struct nfc_jni_native_data*)e->GetIntField(o, f);
}

struct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e)
{
   return exported_nat;
}

static nfc_jni_native_monitor_t *nfc_jni_native_monitor = NULL;

nfc_jni_native_monitor_t* nfc_jni_init_monitor(void)
{

   pthread_mutexattr_t recursive_attr;

   pthread_mutexattr_init(&recursive_attr);
   pthread_mutexattr_settype(&recursive_attr, PTHREAD_MUTEX_RECURSIVE_NP);

   if(nfc_jni_native_monitor == NULL)
   {
      nfc_jni_native_monitor = (nfc_jni_native_monitor_t*)malloc(sizeof(nfc_jni_native_monitor_t));
   }

   if(nfc_jni_native_monitor != NULL)
   {
      memset(nfc_jni_native_monitor, 0, sizeof(nfc_jni_native_monitor_t));

      if(pthread_mutex_init(&nfc_jni_native_monitor->reentrance_mutex, &recursive_attr) == -1)
      {
         LOGE("NFC Manager Reentrance Mutex creation returned 0x%08x", errno);
         return NULL;
      }

      if(pthread_mutex_init(&nfc_jni_native_monitor->concurrency_mutex, NULL) == -1)
      {
         LOGE("NFC Manager Concurrency Mutex creation returned 0x%08x", errno);
         return NULL;
      }

      if(!listInit(&nfc_jni_native_monitor->sem_list))
      {
         LOGE("NFC Manager Semaphore List creation failed");
         return NULL;
      }

      LIST_INIT(&nfc_jni_native_monitor->incoming_socket_head);

      if(pthread_mutex_init(&nfc_jni_native_monitor->incoming_socket_mutex, NULL) == -1)
      {
         LOGE("NFC Manager incoming socket mutex creation returned 0x%08x", errno);
         return NULL;
      }

      if(pthread_cond_init(&nfc_jni_native_monitor->incoming_socket_cond, NULL) == -1)
      {
         LOGE("NFC Manager incoming socket condition creation returned 0x%08x", errno);
         return NULL;
      }

}

   return nfc_jni_native_monitor;
} 

nfc_jni_native_monitor_t* nfc_jni_get_monitor(void)
{
   return nfc_jni_native_monitor;
}
   

phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;

   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mHandle", "I");

   return e->GetIntField(o, f);
}

jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;

   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mMode", "S");

   return e->GetShortField(o, f);
}


int nfc_jni_get_connected_tech_index(JNIEnv *e, jobject o)
{

   jclass c;
   jfieldID f;

   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mConnectedTechnology", "I");

   return e->GetIntField(o, f);

}

jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;
   int connectedTech = -1;

   int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
   jintArray techTypes = nfc_jni_get_nfc_tag_type(e, o);

   if ((connectedTechIndex != -1) && (techTypes != NULL) &&
           (connectedTechIndex < e->GetArrayLength(techTypes))) {
       jint* technologies = e->GetIntArrayElements(techTypes, 0);
       if (technologies != NULL) {
           connectedTech = technologies[connectedTechIndex];
           e->ReleaseIntArrayElements(techTypes, technologies, JNI_ABORT);
       }
   }

   return connectedTech;

}

jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;
   jint connectedLibNfcType = -1;

   int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mTechLibNfcTypes", "[I");
   jintArray libNfcTypes =  (jintArray) e->GetObjectField(o, f);

   if ((connectedTechIndex != -1) && (libNfcTypes != NULL) &&
           (connectedTechIndex < e->GetArrayLength(libNfcTypes))) {
       jint* types = e->GetIntArrayElements(libNfcTypes, 0);
       if (types != NULL) {
           connectedLibNfcType = types[connectedTechIndex];
           e->ReleaseIntArrayElements(libNfcTypes, types, JNI_ABORT);
       }
   }
   return connectedLibNfcType;

}

phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;
   phLibNfc_Handle connectedHandle = -1;

   int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mTechHandles", "[I");
   jintArray techHandles =  (jintArray) e->GetObjectField(o, f);

   if ((connectedTechIndex != -1) && (techHandles != NULL) &&
           (connectedTechIndex < e->GetArrayLength(techHandles))) {
       jint* handles = e->GetIntArrayElements(techHandles, 0);
       if (handles != NULL) {
           connectedHandle = handles[connectedTechIndex];
           e->ReleaseIntArrayElements(techHandles, handles, JNI_ABORT);
       }
   }
   return connectedHandle;

}

phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o)
{
   jclass c;
   jfieldID f;

   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mHandle", "I");

   return e->GetIntField(o, f);
}

jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o)
{
  jclass c;
  jfieldID f;
  jintArray techtypes;
   
  c = e->GetObjectClass(o);
  f = e->GetFieldID(c, "mTechList","[I");

  /* Read the techtypes  */
  techtypes = (jintArray) e->GetObjectField(o, f);

  return techtypes;
}



//Display status code
const char* nfc_jni_get_status_name(NFCSTATUS status)
{
   #define STATUS_ENTRY(status) { status, #status }
 
   struct status_entry {
      NFCSTATUS   code;
      const char  *name;
   };

   const struct status_entry sNameTable[] = {
      STATUS_ENTRY(NFCSTATUS_SUCCESS),
      STATUS_ENTRY(NFCSTATUS_FAILED),
      STATUS_ENTRY(NFCSTATUS_INVALID_PARAMETER),
      STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_RESOURCES),
      STATUS_ENTRY(NFCSTATUS_TARGET_LOST),
      STATUS_ENTRY(NFCSTATUS_INVALID_HANDLE),
      STATUS_ENTRY(NFCSTATUS_MULTIPLE_TAGS),
      STATUS_ENTRY(NFCSTATUS_ALREADY_REGISTERED),
      STATUS_ENTRY(NFCSTATUS_FEATURE_NOT_SUPPORTED),
      STATUS_ENTRY(NFCSTATUS_SHUTDOWN),
      STATUS_ENTRY(NFCSTATUS_ABORTED),
      STATUS_ENTRY(NFCSTATUS_REJECTED ),
      STATUS_ENTRY(NFCSTATUS_NOT_INITIALISED),
      STATUS_ENTRY(NFCSTATUS_PENDING),
      STATUS_ENTRY(NFCSTATUS_BUFFER_TOO_SMALL),
      STATUS_ENTRY(NFCSTATUS_ALREADY_INITIALISED),
      STATUS_ENTRY(NFCSTATUS_BUSY),
      STATUS_ENTRY(NFCSTATUS_TARGET_NOT_CONNECTED),
      STATUS_ENTRY(NFCSTATUS_MULTIPLE_PROTOCOLS),
      STATUS_ENTRY(NFCSTATUS_DESELECTED),
      STATUS_ENTRY(NFCSTATUS_INVALID_DEVICE),
      STATUS_ENTRY(NFCSTATUS_MORE_INFORMATION),
      STATUS_ENTRY(NFCSTATUS_RF_TIMEOUT),
      STATUS_ENTRY(NFCSTATUS_RF_ERROR),
      STATUS_ENTRY(NFCSTATUS_BOARD_COMMUNICATION_ERROR),
      STATUS_ENTRY(NFCSTATUS_INVALID_STATE),
      STATUS_ENTRY(NFCSTATUS_NOT_REGISTERED),
      STATUS_ENTRY(NFCSTATUS_RELEASED),
      STATUS_ENTRY(NFCSTATUS_NOT_ALLOWED),
      STATUS_ENTRY(NFCSTATUS_INVALID_REMOTE_DEVICE),
      STATUS_ENTRY(NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED),
      STATUS_ENTRY(NFCSTATUS_READ_FAILED),
      STATUS_ENTRY(NFCSTATUS_WRITE_FAILED),
      STATUS_ENTRY(NFCSTATUS_NO_NDEF_SUPPORT),
      STATUS_ENTRY(NFCSTATUS_EOF_NDEF_CONTAINER_REACHED),
      STATUS_ENTRY(NFCSTATUS_INVALID_RECEIVE_LENGTH),
      STATUS_ENTRY(NFCSTATUS_INVALID_FORMAT),
      STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_STORAGE),
      STATUS_ENTRY(NFCSTATUS_FORMAT_ERROR),
   };

   int i = sizeof(sNameTable)/sizeof(status_entry);
 
   while(i>0)
   {
      i--;
      if (sNameTable[i].code == PHNFCSTATUS(status))
      {
         return sNameTable[i].name;
      }
   }

   return "UNKNOWN";
}

int addTechIfNeeded(int *techList, int* handleList, int* typeList, int listSize,
        int maxListSize, int techToAdd, int handleToAdd, int typeToAdd) {
    bool found = false;
    for (int i = 0; i < listSize; i++) {
        if (techList[i] == techToAdd) {
            found = true;
            break;
        }
    }
    if (!found && listSize < maxListSize) {
        techList[listSize] = techToAdd;
        handleList[listSize] = handleToAdd;
        typeList[listSize] = typeToAdd;
        return listSize + 1;
    }
    else {
        return listSize;
    }
}


#define MAX_NUM_TECHNOLOGIES 32

/*
 *  Utility to get a technology tree and a corresponding handle list from a detected tag.
 */
void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
        uint8_t count, jintArray* techList, jintArray* handleList,
        jintArray* libnfcTypeList)
{
   int technologies[MAX_NUM_TECHNOLOGIES];
   int handles[MAX_NUM_TECHNOLOGIES];
   int libnfctypes[MAX_NUM_TECHNOLOGIES];

   int index = 0;
   // TODO: This counts from up to down because on multi-protocols, the
   // ISO handle is usually the second, and we prefer the ISO. Should implement
   // a method to find the "preferred handle order" and use that instead,
   // since we shouldn't have dependencies on the tech list ordering.
   for (int target = count - 1; target >= 0; target--) {
       int type = devList[target].psRemoteDevInfo->RemDevType;
       int handle = devList[target].hTargetDev;
       switch (type)
       {
          case phNfc_eISO14443_A_PICC:
          case phNfc_eISO14443_4A_PICC:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
              break;
            }
          case phNfc_eISO14443_4B_PICC:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
            }break;
          case phNfc_eISO14443_3A_PICC:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
            }break;
          case phNfc_eISO14443_B_PICC:
            {
              // TODO a bug in libnfc will cause 14443-3B only cards
              // to be returned as this type as well, but these cards
              // are very rare. Hence assume it's -4B
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
            }break;
          case phNfc_eISO15693_PICC:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO15693, handle, type);
            }break;
          case phNfc_eMifare_PICC:
            {
              // We don't want to be too clever here; libnfc has already determined
              // it's a Mifare, so we only check for UL, for all other tags
              // we assume it's a mifare classic. This should make us more
              // future-proof.
              int sak = devList[target].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
              switch(sak)
              {
                case 0x00:
                  // could be UL or UL-C
                  index = addTechIfNeeded(technologies, handles, libnfctypes,
                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_UL, handle, type);
                  index = addTechIfNeeded(technologies, handles, libnfctypes,
                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
                  break;
                default:
                  index = addTechIfNeeded(technologies, handles, libnfctypes,
                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, handle, type);
                  index = addTechIfNeeded(technologies, handles, libnfctypes,
                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
                  break;
              }
            }break;
          case phNfc_eFelica_PICC:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_FELICA, handle, type);
            }break;
          case phNfc_eJewel_PICC:
            {
              // Jewel represented as NfcA
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
            }break;
          default:
            {
              index = addTechIfNeeded(technologies, handles, libnfctypes,
                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_UNKNOWN, handle, type);
            }
        }
   }

   // Build the Java arrays
   if (techList != NULL) {
       *techList = e->NewIntArray(index);
       jint* techItems = e->GetIntArrayElements(*techList, NULL);
       for (int i = 0; i < index; i++) {
           techItems[i] = technologies[i];
       }
       e->ReleaseIntArrayElements(*techList, techItems, 0);
   }

   if (handleList != NULL) {
       *handleList = e->NewIntArray(index);
       jint* handleItems = e->GetIntArrayElements(*handleList, NULL);
       for (int i = 0; i < index; i++) {
           handleItems[i] = handles[i];
       }
       e->ReleaseIntArrayElements(*handleList, handleItems, 0);
   }

   if (libnfcTypeList != NULL) {
       *libnfcTypeList = e->NewIntArray(index);

       jint* typeItems = e->GetIntArrayElements(*libnfcTypeList, NULL);
       for (int i = 0; i < index; i++) {
           typeItems[i] = libnfctypes[i];
       }
       e->ReleaseIntArrayElements(*libnfcTypeList, typeItems, 0);
   }
}

} // namespace android
