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

   ALOGD("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) {
        ALOGE("Current thread is not attached to VM");
        phLibNfc_Mgt_Recovery();
        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)
   {
      ALOGE("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))
   {
      ALOGE("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))
   {
      ALOGE("Failed to destroy semaphore (errno=0x%08x)", errno);
   }

   /* Remove from active semaphore list */
   if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData))
   {
      ALOGE("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;
      ALOGD("Find class error\n");
   }


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

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

   *cached_obj = e->NewGlobalRef(obj);
   if(*cached_obj == NULL)
   {
      e->DeleteLocalRef(obj);
      ALOGD("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)
      {
         ALOGE("NFC Manager Reentrance Mutex creation returned 0x%08x", errno);
         return NULL;
      }

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

      if(!listInit(&nfc_jni_native_monitor->sem_list))
      {
         ALOGE("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)
      {
         ALOGE("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)
      {
         ALOGE("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, "mConnectedTechIndex", "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;

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

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

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);
              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);
                  break;
                default:
                  index = addTechIfNeeded(technologies, handles, libnfctypes,
                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, 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);
       e->SetIntArrayRegion(*techList, 0, index, technologies);
   }

   if (handleList != NULL) {
       *handleList = e->NewIntArray(index);
       e->SetIntArrayRegion(*handleList, 0, index, handles);
   }

   if (libnfcTypeList != NULL) {
       *libnfcTypeList = e->NewIntArray(index);
       e->SetIntArrayRegion(*libnfcTypeList, 0, index, libnfctypes);
   }
}

} // namespace android
