/*
 * Copyright (C) 2013 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/license/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.
 */

#define LOG_TAG "FuseLocationProvider"
#define LOG_NDEBUG  0

#define WAKE_LOCK_NAME  "FLP"
#define LOCATION_CLASS_NAME "android/location/Location"

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "hardware/fused_location.h"
#include "hardware_legacy/power.h"

static jobject sCallbacksObj = NULL;
static JNIEnv *sCallbackEnv = NULL;
static hw_device_t* sHardwareDevice = NULL;

static jmethodID sOnLocationReport = NULL;
static jmethodID sOnDataReport = NULL;
static jmethodID sOnGeofenceTransition = NULL;
static jmethodID sOnGeofenceMonitorStatus = NULL;
static jmethodID sOnGeofenceAdd = NULL;
static jmethodID sOnGeofenceRemove = NULL;
static jmethodID sOnGeofencePause = NULL;
static jmethodID sOnGeofenceResume = NULL;

static const FlpLocationInterface* sFlpInterface = NULL;
static const FlpDiagnosticInterface* sFlpDiagnosticInterface = NULL;
static const FlpGeofencingInterface* sFlpGeofencingInterface = NULL;
static const FlpDeviceContextInterface* sFlpDeviceContextInterface = NULL;

namespace android {

static inline void CheckExceptions(JNIEnv* env, const char* methodName) {
  if(!env->ExceptionCheck()) {
    return;
  }

  ALOGE("An exception was thrown by '%s'.", methodName);
  LOGE_EX(env);
  env->ExceptionClear();
}

static inline void ThrowOnError(
    JNIEnv* env,
    int resultCode,
    const char* methodName) {
  if(resultCode == FLP_RESULT_SUCCESS) {
    return;
  }

  ALOGE("Error %d in '%s'", resultCode, methodName);
  jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
  env->ThrowNew(exceptionClass, methodName);
}

static bool IsValidCallbackThread() {
  JNIEnv* env = AndroidRuntime::getJNIEnv();

  if(sCallbackEnv == NULL || sCallbackEnv != env) {
    ALOGE("CallbackThread check fail: env=%p, expected=%p", env, sCallbackEnv);
    return false;
  }

  return true;
}

static int SetThreadEvent(ThreadEvent event) {
  JavaVM* javaVm = AndroidRuntime::getJavaVM();

  switch(event) {
    case ASSOCIATE_JVM:
    {
      if(sCallbackEnv != NULL) {
        ALOGE(
            "Attempted to associate callback in '%s'. Callback already associated.",
            __FUNCTION__
            );
        return FLP_RESULT_ERROR;
      }

      JavaVMAttachArgs args = {
          JNI_VERSION_1_6,
          "FLP Service Callback Thread",
          /* group */ NULL
      };

      jint attachResult = javaVm->AttachCurrentThread(&sCallbackEnv, &args);
      if (attachResult != 0) {
        ALOGE("Callback thread attachment error: %d", attachResult);
        return FLP_RESULT_ERROR;
      }

      ALOGV("Callback thread attached: %p", sCallbackEnv);
      break;
    }
    case DISASSOCIATE_JVM:
    {
      if (!IsValidCallbackThread()) {
        ALOGE(
            "Attempted to dissasociate an unnownk callback thread : '%s'.",
            __FUNCTION__
            );
        return FLP_RESULT_ERROR;
      }

      if (javaVm->DetachCurrentThread() != 0) {
        return FLP_RESULT_ERROR;
      }

      sCallbackEnv = NULL;
      break;
    }
    default:
      ALOGE("Invalid ThreadEvent request %d", event);
      return FLP_RESULT_ERROR;
  }

  return FLP_RESULT_SUCCESS;
}

/*
 * Initializes the FlpHardwareProvider class from the native side by opening
 * the HW module and obtaining the proper interfaces.
 */
static void ClassInit(JNIEnv* env, jclass clazz) {
  // get references to the Java provider methods
  sOnLocationReport = env->GetMethodID(
      clazz,
      "onLocationReport",
      "([Landroid/location/Location;)V");
  sOnDataReport = env->GetMethodID(
      clazz,
      "onDataReport",
      "(Ljava/lang/String;)V"
      );
  sOnGeofenceTransition = env->GetMethodID(
      clazz,
      "onGeofenceTransition",
      "(ILandroid/location/Location;IJI)V"
      );
  sOnGeofenceMonitorStatus = env->GetMethodID(
      clazz,
      "onGeofenceMonitorStatus",
      "(IILandroid/location/Location;)V"
      );
  sOnGeofenceAdd = env->GetMethodID(clazz, "onGeofenceAdd", "(II)V");
  sOnGeofenceRemove = env->GetMethodID(clazz, "onGeofenceRemove", "(II)V");
  sOnGeofencePause = env->GetMethodID(clazz, "onGeofencePause", "(II)V");
  sOnGeofenceResume = env->GetMethodID(clazz, "onGeofenceResume", "(II)V");
}

/*
 * Helper function to unwrap a java object back into a FlpLocation structure.
 */
static void TranslateFromObject(
    JNIEnv* env,
    jobject locationObject,
    FlpLocation& location) {
  location.size = sizeof(FlpLocation);
  location.flags = 0;

  jclass locationClass = env->GetObjectClass(locationObject);

  jmethodID getLatitude = env->GetMethodID(locationClass, "getLatitude", "()D");
  location.latitude = env->CallDoubleMethod(locationObject, getLatitude);
  jmethodID getLongitude = env->GetMethodID(locationClass, "getLongitude", "()D");
  location.longitude = env->CallDoubleMethod(locationObject, getLongitude);
  jmethodID getTime = env->GetMethodID(locationClass, "getTime", "()J");
  location.timestamp = env->CallLongMethod(locationObject, getTime);
  location.flags |= FLP_LOCATION_HAS_LAT_LONG;

  jmethodID hasAltitude = env->GetMethodID(locationClass, "hasAltitude", "()Z");
  if (env->CallBooleanMethod(locationObject, hasAltitude)) {
    jmethodID getAltitude = env->GetMethodID(locationClass, "getAltitude", "()D");
    location.altitude = env->CallDoubleMethod(locationObject, getAltitude);
    location.flags |= FLP_LOCATION_HAS_ALTITUDE;
  }

  jmethodID hasSpeed = env->GetMethodID(locationClass, "hasSpeed", "()Z");
  if (env->CallBooleanMethod(locationObject, hasSpeed)) {
    jmethodID getSpeed = env->GetMethodID(locationClass, "getSpeed", "()F");
    location.speed = env->CallFloatMethod(locationObject, getSpeed);
    location.flags |= FLP_LOCATION_HAS_SPEED;
  }

  jmethodID hasBearing = env->GetMethodID(locationClass, "hasBearing", "()Z");
  if (env->CallBooleanMethod(locationObject, hasBearing)) {
    jmethodID getBearing = env->GetMethodID(locationClass, "getBearing", "()F");
    location.bearing = env->CallFloatMethod(locationObject, getBearing);
    location.flags |= FLP_LOCATION_HAS_BEARING;
  }

  jmethodID hasAccuracy = env->GetMethodID(locationClass, "hasAccuracy", "()Z");
  if (env->CallBooleanMethod(locationObject, hasAccuracy)) {
    jmethodID getAccuracy = env->GetMethodID(
        locationClass,
        "getAccuracy",
        "()F"
        );
    location.accuracy = env->CallFloatMethod(locationObject, getAccuracy);
    location.flags |= FLP_LOCATION_HAS_ACCURACY;
  }

  // TODO: wire sources_used if Location class exposes them
}

/*
 * Helper function to unwrap FlpBatchOptions from the Java Runtime calls.
 */
static void TranslateFromObject(
    JNIEnv* env,
    jobject batchOptionsObject,
    FlpBatchOptions& batchOptions) {
  jclass batchOptionsClass = env->GetObjectClass(batchOptionsObject);

  jmethodID getMaxPower = env->GetMethodID(
      batchOptionsClass,
      "getMaxPowerAllocationInMW",
      "()D"
      );
  batchOptions.max_power_allocation_mW = env->CallDoubleMethod(
      batchOptionsObject,
      getMaxPower
      );

  jmethodID getPeriod = env->GetMethodID(
      batchOptionsClass,
      "getPeriodInNS",
      "()J"
      );
  batchOptions.period_ns = env->CallLongMethod(batchOptionsObject, getPeriod);

  jmethodID getSourcesToUse = env->GetMethodID(
      batchOptionsClass,
      "getSourcesToUse",
      "()I"
      );
  batchOptions.sources_to_use = env->CallIntMethod(
      batchOptionsObject,
      getSourcesToUse
      );

  jmethodID getFlags = env->GetMethodID(batchOptionsClass, "getFlags", "()I");
  batchOptions.flags = env->CallIntMethod(batchOptionsObject, getFlags);
}

/*
 * Helper function to transform FlpLocation into a java object.
 */
static void TranslateToObject(const FlpLocation* location, jobject& locationObject) {
  jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
  jmethodID locationCtor = sCallbackEnv->GetMethodID(
      locationClass,
      "<init>",
      "(Ljava/lang/String;)V"
      );

  // the provider is set in the upper JVM layer
  locationObject = sCallbackEnv->NewObject(locationClass, locationCtor, NULL);
  jint flags = location->flags;

  // set the valid information in the object
  if (flags & FLP_LOCATION_HAS_LAT_LONG) {
    jmethodID setLatitude = sCallbackEnv->GetMethodID(
        locationClass,
        "setLatitude",
        "(D)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setLatitude, location->latitude);

    jmethodID setLongitude = sCallbackEnv->GetMethodID(
        locationClass,
        "setLongitude",
        "(D)V"
        );
    sCallbackEnv->CallVoidMethod(
        locationObject,
        setLongitude,
        location->longitude
        );

    jmethodID setTime = sCallbackEnv->GetMethodID(
        locationClass,
        "setTime",
        "(J)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setTime, location->timestamp);
  }

  if (flags & FLP_LOCATION_HAS_ALTITUDE) {
    jmethodID setAltitude = sCallbackEnv->GetMethodID(
        locationClass,
        "setAltitude",
        "(D)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setAltitude, location->altitude);
  }

  if (flags & FLP_LOCATION_HAS_SPEED) {
    jmethodID setSpeed = sCallbackEnv->GetMethodID(
        locationClass,
        "setSpeed",
        "(F)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setSpeed, location->speed);
  }

  if (flags & FLP_LOCATION_HAS_BEARING) {
    jmethodID setBearing = sCallbackEnv->GetMethodID(
        locationClass,
        "setBearing",
        "(F)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setBearing, location->bearing);
  }

  if (flags & FLP_LOCATION_HAS_ACCURACY) {
    jmethodID setAccuracy = sCallbackEnv->GetMethodID(
        locationClass,
        "setAccuracy",
        "(F)V"
        );
    sCallbackEnv->CallVoidMethod(locationObject, setAccuracy, location->accuracy);
  }

  // TODO: wire FlpLocation::sources_used when needed
}

/*
 * Helper function to serialize FlpLocation structures.
 */
static void TranslateToObjectArray(
    int32_t locationsCount,
    FlpLocation** locations,
    jobjectArray& locationsArray) {
  jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
  locationsArray = sCallbackEnv->NewObjectArray(
      locationsCount,
      locationClass,
      /* initialElement */ NULL
      );

  for (int i = 0; i < locationsCount; ++i) {
    jobject locationObject = NULL;
    TranslateToObject(locations[i], locationObject);
    sCallbackEnv->SetObjectArrayElement(locationsArray, i, locationObject);
    sCallbackEnv->DeleteLocalRef(locationObject);
  }
}

static void LocationCallback(int32_t locationsCount, FlpLocation** locations) {
  if(!IsValidCallbackThread()) {
    return;
  }

  if(locationsCount == 0 || locations == NULL) {
    ALOGE(
        "Invalid LocationCallback. Count: %d, Locations: %p",
        locationsCount,
        locations
        );
    return;
  }

  jobjectArray locationsArray = NULL;
  TranslateToObjectArray(locationsCount, locations, locationsArray);

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnLocationReport,
      locationsArray
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void AcquireWakelock() {
  acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
}

static void ReleaseWakelock() {
  release_wake_lock(WAKE_LOCK_NAME);
}

FlpCallbacks sFlpCallbacks = {
  sizeof(FlpCallbacks),
  LocationCallback,
  AcquireWakelock,
  ReleaseWakelock,
  SetThreadEvent
};

static void ReportData(char* data, int length) {
  jstring stringData = NULL;

  if(length != 0 && data != NULL) {
    stringData = sCallbackEnv->NewString(reinterpret_cast<jchar*>(data), length);
  } else {
    ALOGE("Invalid ReportData callback. Length: %d, Data: %p", length, data);
    return;
  }

  sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnDataReport, stringData);
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

FlpDiagnosticCallbacks sFlpDiagnosticCallbacks = {
  sizeof(FlpDiagnosticCallbacks),
  SetThreadEvent,
  ReportData
};

static void GeofenceTransitionCallback(
    int32_t geofenceId,
    FlpLocation* location,
    int32_t transition,
    FlpUtcTime timestamp,
    uint32_t sourcesUsed
    ) {
  if(!IsValidCallbackThread()) {
    return;
  }

  if(location == NULL) {
    ALOGE("GeofenceTransition received with invalid location: %p", location);
    return;
  }

  jobject locationObject = NULL;
  TranslateToObject(location, locationObject);

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnGeofenceTransition,
      geofenceId,
      locationObject,
      transition,
      timestamp,
      sourcesUsed
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void GeofenceMonitorStatusCallback(
    int32_t status,
    uint32_t source,
    FlpLocation* lastLocation) {
  if(!IsValidCallbackThread()) {
    return;
  }

  jobject locationObject = NULL;
  if(lastLocation != NULL) {
    TranslateToObject(lastLocation, locationObject);
  }

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnGeofenceMonitorStatus,
      status,
      source,
      locationObject
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void GeofenceAddCallback(int32_t geofenceId, int32_t result) {
  if(!IsValidCallbackThread()) {
    return;
  }

  sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnGeofenceAdd, geofenceId, result);
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void GeofenceRemoveCallback(int32_t geofenceId, int32_t result) {
  if(!IsValidCallbackThread()) {
    return;
  }

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnGeofenceRemove,
      geofenceId,
      result
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void GeofencePauseCallback(int32_t geofenceId, int32_t result) {
  if(!IsValidCallbackThread()) {
    return;
  }

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnGeofencePause,
      geofenceId,
      result
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

static void GeofenceResumeCallback(int32_t geofenceId, int32_t result) {
  if(!IsValidCallbackThread()) {
    return;
  }

  sCallbackEnv->CallVoidMethod(
      sCallbacksObj,
      sOnGeofenceResume,
      geofenceId,
      result
      );
  CheckExceptions(sCallbackEnv, __FUNCTION__);
}

FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
  sizeof(FlpGeofenceCallbacks),
  GeofenceTransitionCallback,
  GeofenceMonitorStatusCallback,
  GeofenceAddCallback,
  GeofenceRemoveCallback,
  GeofencePauseCallback,
  GeofenceResumeCallback,
  SetThreadEvent
};

/*
 * Initializes the Fused Location Provider in the native side. It ensures that
 * the Flp interfaces are initialized properly.
 */
static void Init(JNIEnv* env, jobject obj) {
  if(sHardwareDevice != NULL) {
    ALOGD("Hardware Device already opened.");
    return;
  }

  const hw_module_t* module = NULL;
  int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, &module);
  if(err != 0) {
    ALOGE("Error hw_get_module '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
    return;
  }

  err = module->methods->open(
        module, 
        FUSED_LOCATION_HARDWARE_MODULE_ID, &sHardwareDevice);
  if(err != 0) {
    ALOGE("Error opening device '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
    return;
  }

  sFlpInterface = NULL;
  flp_device_t* flp_device = reinterpret_cast<flp_device_t*>(sHardwareDevice);
  sFlpInterface = flp_device->get_flp_interface(flp_device);

  if(sFlpInterface != NULL) {
    sFlpDiagnosticInterface = reinterpret_cast<const FlpDiagnosticInterface*>(
        sFlpInterface->get_extension(FLP_DIAGNOSTIC_INTERFACE)
        );

    sFlpGeofencingInterface = reinterpret_cast<const FlpGeofencingInterface*>(
        sFlpInterface->get_extension(FLP_GEOFENCING_INTERFACE)
        );

    sFlpDeviceContextInterface = reinterpret_cast<const FlpDeviceContextInterface*>(
        sFlpInterface->get_extension(FLP_DEVICE_CONTEXT_INTERFACE)
        );
  }

  if(sCallbacksObj == NULL) {
    sCallbacksObj = env->NewGlobalRef(obj);
  }

  // initialize the Flp interfaces
  if(sFlpInterface == NULL || sFlpInterface->init(&sFlpCallbacks) != 0) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  if(sFlpDiagnosticInterface != NULL) {
    sFlpDiagnosticInterface->init(&sFlpDiagnosticCallbacks);
  }

  if(sFlpGeofencingInterface != NULL) {
    sFlpGeofencingInterface->init(&sFlpGeofenceCallbacks);
  }

  // TODO: inject any device context if when needed
}

static jboolean IsSupported(JNIEnv* env, jclass clazz) {
  return sFlpInterface != NULL;
}

static jint GetBatchSize(JNIEnv* env, jobject object) {
  if(sFlpInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  return sFlpInterface->get_batch_size();
}

static void StartBatching(
    JNIEnv* env,
    jobject object,
    jint id,
    jobject optionsObject) {
  if(sFlpInterface == NULL || optionsObject == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  FlpBatchOptions options;
  TranslateFromObject(env, optionsObject, options);
  int result = sFlpInterface->start_batching(id, &options);
  ThrowOnError(env, result, __FUNCTION__);
}

static void UpdateBatchingOptions(
    JNIEnv* env,
    jobject object,
    jint id,
    jobject optionsObject) {
  if(sFlpInterface == NULL || optionsObject == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  FlpBatchOptions options;
  TranslateFromObject(env, optionsObject, options);
  int result = sFlpInterface->update_batching_options(id, &options);
  ThrowOnError(env, result, __FUNCTION__);
}

static void StopBatching(JNIEnv* env, jobject object, jint id) {
  if(sFlpInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpInterface->stop_batching(id);
}

static void Cleanup(JNIEnv* env, jobject object) {
  if(sFlpInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpInterface->cleanup();

  if(sCallbacksObj != NULL) {
    env->DeleteGlobalRef(sCallbacksObj);
    sCallbacksObj = NULL;
  }

  sFlpInterface = NULL;
  sFlpDiagnosticInterface = NULL;
  sFlpDeviceContextInterface = NULL;
  sFlpGeofencingInterface = NULL;

  if(sHardwareDevice != NULL) {
    sHardwareDevice->close(sHardwareDevice);
    sHardwareDevice = NULL;
  }
}

static void GetBatchedLocation(JNIEnv* env, jobject object, jint lastNLocations) {
  if(sFlpInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpInterface->get_batched_location(lastNLocations);
}

static void InjectLocation(JNIEnv* env, jobject object, jobject locationObject) {
  if(locationObject == NULL) {
    ALOGE("Invalid location for injection: %p", locationObject);
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  if(sFlpInterface == NULL) {
    // there is no listener, bail
    return;
  }

  FlpLocation location;
  TranslateFromObject(env, locationObject, location);
  int result = sFlpInterface->inject_location(&location);
  if (result != FLP_RESULT_ERROR) {
    // do not throw but log, this operation should be fire and forget
    ALOGE("Error %d in '%s'", result, __FUNCTION__);
  }
}

static jboolean IsDiagnosticSupported() {
  return sFlpDiagnosticInterface != NULL;
}

static void InjectDiagnosticData(JNIEnv* env, jobject object, jstring stringData) {
  if(stringData == NULL) {
    ALOGE("Invalid diagnostic data for injection: %p", stringData);
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  if(sFlpDiagnosticInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  int length = env->GetStringLength(stringData);
  const jchar* data = env->GetStringChars(stringData, /* isCopy */ NULL);
  if(data == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  int result = sFlpDiagnosticInterface->inject_data((char*) data, length);
  ThrowOnError(env, result, __FUNCTION__);
}

static jboolean IsDeviceContextSupported() {
  return sFlpDeviceContextInterface != NULL;
}

static void InjectDeviceContext(JNIEnv* env, jobject object, jint enabledMask) {
  if(sFlpDeviceContextInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  int result = sFlpDeviceContextInterface->inject_device_context(enabledMask);
  ThrowOnError(env, result, __FUNCTION__);
}

static jboolean IsGeofencingSupported() {
  return sFlpGeofencingInterface != NULL;
}

static void AddGeofences(
    JNIEnv* env,
    jobject object,
    jintArray geofenceIdsArray,
    jobjectArray geofencesArray) {
  if(geofencesArray == NULL) {
    ALOGE("Invalid Geofences to add: %p", geofencesArray);
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  if (sFlpGeofencingInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  jint geofencesCount = env->GetArrayLength(geofenceIdsArray);
  Geofence* geofences = new Geofence[geofencesCount];
  if (geofences == NULL) {
    ThrowOnError(env, FLP_RESULT_INSUFFICIENT_MEMORY, __FUNCTION__);
  }

  jint* ids = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL);
  for (int i = 0; i < geofencesCount; ++i) {
    geofences[i].geofence_id = ids[i];

    // TODO: fill in the GeofenceData

    // TODO: fill in the GeofenceOptions
  }

  sFlpGeofencingInterface->add_geofences(geofencesCount, &geofences);
  if (geofences != NULL) delete[] geofences;
}

static void PauseGeofence(JNIEnv* env, jobject object, jint geofenceId) {
  if(sFlpGeofencingInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpGeofencingInterface->pause_geofence(geofenceId);
}

static void ResumeGeofence(
    JNIEnv* env,
    jobject object,
    jint geofenceId,
    jint monitorTransitions) {
  if(sFlpGeofencingInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpGeofencingInterface->resume_geofence(geofenceId, monitorTransitions);
}

static void ModifyGeofenceOption(
    JNIEnv* env,
    jobject object,
    jint geofenceId,
    jint lastTransition,
    jint monitorTransitions,
    jint notificationResponsiveness,
    jint unknownTimer,
    jint sourcesToUse) {
  if(sFlpGeofencingInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  GeofenceOptions options = {
      lastTransition,
      monitorTransitions,
      notificationResponsiveness,
      unknownTimer,
      (uint32_t)sourcesToUse
  };

  sFlpGeofencingInterface->modify_geofence_option(geofenceId, &options);
}

static void RemoveGeofences(
    JNIEnv* env,
    jobject object,
    jintArray geofenceIdsArray) {
  if(sFlpGeofencingInterface == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  jsize geofenceIdsCount = env->GetArrayLength(geofenceIdsArray);
  jint* geofenceIds = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL);
  if(geofenceIds == NULL) {
    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
  }

  sFlpGeofencingInterface->remove_geofences(geofenceIdsCount, geofenceIds);
}

static JNINativeMethod sMethods[] = {
  //{"name", "signature", functionPointer }
  {"nativeClassInit", "()V", reinterpret_cast<void*>(ClassInit)},
  {"nativeInit", "()V", reinterpret_cast<void*>(Init)},
  {"nativeCleanup", "()V", reinterpret_cast<void*>(Cleanup)},
  {"nativeIsSupported", "()Z", reinterpret_cast<void*>(IsSupported)},
  {"nativeGetBatchSize", "()I", reinterpret_cast<void*>(GetBatchSize)},
  {"nativeStartBatching", 
        "(ILandroid/location/FusedBatchOptions;)V", 
        reinterpret_cast<void*>(StartBatching)},
  {"nativeUpdateBatchingOptions", 
        "(ILandroid/location/FusedBatchOptions;)V", 
        reinterpret_cast<void*>(UpdateBatchingOptions)},
  {"nativeStopBatching", "(I)V", reinterpret_cast<void*>(StopBatching)},
  {"nativeRequestBatchedLocation", 
        "(I)V", 
        reinterpret_cast<void*>(GetBatchedLocation)},
  {"nativeInjectLocation", 
        "(Landroid/location/Location;)V", 
        reinterpret_cast<void*>(InjectLocation)},
  {"nativeIsDiagnosticSupported", 
        "()Z", 
        reinterpret_cast<void*>(IsDiagnosticSupported)},
  {"nativeInjectDiagnosticData", 
        "(Ljava/lang/String;)V", 
        reinterpret_cast<void*>(InjectDiagnosticData)},
  {"nativeIsDeviceContextSupported", 
        "()Z", 
        reinterpret_cast<void*>(IsDeviceContextSupported)},
  {"nativeInjectDeviceContext", 
        "(I)V", 
        reinterpret_cast<void*>(InjectDeviceContext)},
  {"nativeIsGeofencingSupported", 
        "()Z", 
        reinterpret_cast<void*>(IsGeofencingSupported)},
  {"nativeAddGeofences", 
        "([I[Landroid/location/Geofence;)V", 
        reinterpret_cast<void*>(AddGeofences)},
  {"nativePauseGeofence", "(I)V", reinterpret_cast<void*>(PauseGeofence)},
  {"nativeResumeGeofence", "(II)V", reinterpret_cast<void*>(ResumeGeofence)},
  {"nativeModifyGeofenceOption", 
        "(IIIIII)V", 
        reinterpret_cast<void*>(ModifyGeofenceOption)},
  {"nativeRemoveGeofences", "([I)V", reinterpret_cast<void*>(RemoveGeofences)}
};

/*
 * Registration method invoked on JNI Load.
 */
int register_android_server_location_FlpHardwareProvider(JNIEnv* env) {
  return jniRegisterNativeMethods(
      env,
      "com/android/server/location/FlpHardwareProvider",
      sMethods,
      NELEM(sMethods)
      );
}

} /* name-space Android */
