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

   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;

/*
 * JNI Utils
 */
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 retruned 0x%08x", errno);
         return NULL;
      }

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

      if(!listInit(&nfc_jni_native_monitor->sem_list))
      {
         LOGE("NFC Manager Semaphore List creation retruned 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);
}


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

   c = e->GetObjectClass(o);
   f = e->GetFieldID(c, "mHandle", "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 listSize, int maxListSize,
        int techToAdd, int handleToAdd) {
    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;
        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)
{
   int technologies[MAX_NUM_TECHNOLOGIES];
   int handles[MAX_NUM_TECHNOLOGIES];
   int index = 0;
   for (int target = 0; target < count; 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, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_4, handle);
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3A, handle);

              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_NDEF_FORMATABLE, handle);
              break;
            }
          case phNfc_eISO14443_4B_PICC:
            {
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_4, handle);
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3B, handle);
            }break;
          case phNfc_eISO14443_3A_PICC:
            {
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3A, handle);
            }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, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_4, handle);
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3B, handle);
            }break;
          case phNfc_eISO15693_PICC:
            {
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO15693, handle);
            }break;
          case phNfc_eMifare_PICC:
            {
              int sak = devList[target].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
              switch(sak)
              {
                case 0x00:
                  // could be UL or UL-C
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_MIFARE_UL, handle);
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3A, handle);
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_NDEF_FORMATABLE, handle);
                  break;
                case 0x08:
                case 0x09:
                case 0x10:
                case 0x11:
                case 0x18:
                case 0x28:
                case 0x38:
                case 0x88:
                case 0x98:
                case 0xB8:
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_MIFARE_CLASSIC, handle);
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_ISO14443_3A, handle);
                  index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_NDEF_FORMATABLE, handle);
                  break;
                case 0x20:
                  // This could be DESfire, but libnfc returns that as ISO14443_4
                  // so we shouldn't hit this case
                default:
                  {
                    index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                      TARGET_TYPE_UNKNOWN, handle);
                  }break;
              }
            }break;
          case phNfc_eFelica_PICC:
            {
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                TARGET_TYPE_FELICA, handle);
            }break;
          case phNfc_eJewel_PICC:
            {
// TODO expose Jewel in the Java APIs
//              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
//                TARGET_TYPE_JEWEL, handle);
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                TARGET_TYPE_ISO14443_3A, handle);
            }break;
          default:
            {
              index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
                TARGET_TYPE_UNKNOWN, handle);
            }
        }
   }
   // Build the Java arrays
   *techList = e->NewIntArray(index);
   *handleList = e->NewIntArray(index);

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

}

} // namespace android
