/*
 * Copyright 2016, 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 "context_hub.h"

#define LOG_NDEBUG 0
#define LOG_TAG "ContextHubService"

#include <inttypes.h>
#include <jni.h>
#include <mutex>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

// TOOD: On master, alphabetize these and move <mutex> into this
//     grouping.
#include <chrono>
#include <unordered_map>
#include <queue>

#include <cutils/log.h>

#include "JNIHelp.h"
#include "core_jni_helpers.h"

static constexpr jint OS_APP_ID = -1;
static constexpr jint INVALID_APP_ID = -2;
static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);

static constexpr jint MIN_APP_ID = 1;
static constexpr jint MAX_APP_ID = 128;

static constexpr size_t MSG_HEADER_SIZE = 4;
static constexpr size_t HEADER_FIELD_MSG_TYPE = 0;
static constexpr size_t HEADER_FIELD_MSG_VERSION = 1;
static constexpr size_t HEADER_FIELD_HUB_HANDLE = 2;
static constexpr size_t HEADER_FIELD_APP_INSTANCE = 3;

static constexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE;
static constexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1;
static constexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2;

// Monotonically increasing clock we use to determine if we can cancel
// a transaction.
using std::chrono::steady_clock;

namespace android {

namespace {

/*
 * Finds the length of a statically-sized array using template trickery that
 * also prevents it from being applied to the wrong type.
 */
template <typename T, size_t N>
constexpr size_t array_length(T (&)[N]) { return N; }

struct jniInfo_s {
    JavaVM *vm;
    jclass contextHubInfoClass;
    jclass contextHubServiceClass;
    jclass memoryRegionsClass;

    jobject jContextHubService;

    jmethodID msgReceiptCallBack;

    jmethodID contextHubInfoCtor;
    jmethodID contextHubInfoSetId;
    jmethodID contextHubInfoSetName;
    jmethodID contextHubInfoSetVendor;
    jmethodID contextHubInfoSetToolchain;
    jmethodID contextHubInfoSetPlatformVersion;
    jmethodID contextHubInfoSetStaticSwVersion;
    jmethodID contextHubInfoSetToolchainVersion;
    jmethodID contextHubInfoSetPeakMips;
    jmethodID contextHubInfoSetStoppedPowerDrawMw;
    jmethodID contextHubInfoSetSleepPowerDrawMw;
    jmethodID contextHubInfoSetPeakPowerDrawMw;
    jmethodID contextHubInfoSetSupportedSensors;
    jmethodID contextHubInfoSetMemoryRegions;
    jmethodID contextHubInfoSetMaxPacketLenBytes;

    jmethodID contextHubServiceMsgReceiptCallback;
    jmethodID contextHubServiceAddAppInstance;
    jmethodID contextHubServiceDeleteAppInstance;
};

struct context_hub_info_s {
    uint32_t *cookies;
    int numHubs;
    const struct context_hub_t *hubs;
    struct context_hub_module_t *contextHubModule;
};

struct app_instance_info_s {
    uint64_t truncName;          // Possibly truncated name for logging
    uint32_t hubHandle;          // Id of the hub this app is on
    jint instanceId;             // system wide unique instance id - assigned
    struct hub_app_info appInfo; // returned from the HAL
};


// If a transaction takes longer than this, we'll allow it to be
// canceled by a new transaction.  Note we do _not_ automatically
// cancel a transaction after this much time.  We can have a
// legal transaction which takes longer than this amount of time,
// as long as no other new transactions are attempted after this
// time has expired.
// TODO(b/31105001): Establish a clean timing approach for all
// of our HAL interactions.
constexpr auto kMinTransactionCancelTime = std::chrono::seconds(29);

/*
 * TODO(ashutoshj): From original code review:
 *
 * So, I feel like we could possible do a better job of organizing this code,
 * and being more C++-y.  Consider something like this:
 * class TxnManager {
 *  public:
 *   TxnManager();
 *   ~TxnManager();
 *   int add(hub_message_e identifier, void *data);
 *   int close();
 *   bool isPending() const;
 *   int fetchData(hub_message_e *identifier, void **data) const;
 *
 *  private:
 *   bool mPending;
 *   mutable std::mutex mLock;
 *   hub_message_e mIdentifier;
 *   void *mData;
 * };
 *
 * And then, for example, we'd have things like:
 * TxnManager::TxnManager() : mPending(false), mLock(), mIdentifier(), mData(nullptr) {}
 * int TxnManager::add(hub_message_e identifier, void *data) {
 *    std::lock_guard<std::mutex> lock(mLock);
 *    mPending = true;
 *    mData = txnData;
 *    mIdentifier = txnIdentifier;
 *    return 0;
 *  }
 * And then calling code would look like:
 *    if (!db.txnManager.add(CONTEXT_HUB_LOAD_APP, txnInfo)) {
 *
 * This would make it clearer the nothing is manipulating any state within TxnManager
 * unsafely and outside of these couple of calls.
 */
struct txnManager_s {
    bool txnPending;              // Is a transaction pending
    std::mutex m;                 // mutex for manager
    hub_messages_e txnIdentifier; // What are we doing
    void *txnData;                // Details
    steady_clock::time_point firstTimeTxnCanBeCanceled;
};

struct contextHubServiceDb_s {
    int initialized;
    context_hub_info_s hubInfo;
    jniInfo_s jniInfo;
    std::queue<jint> freeIds;
    std::unordered_map<jint, app_instance_info_s> appInstances;
    txnManager_s txnManager;
};

}  // unnamed namespace

static contextHubServiceDb_s db;

static bool initTxnManager() {
    txnManager_s *mgr = &db.txnManager;

    mgr->txnData = nullptr;
    mgr->txnPending = false;
    return true;
}

static int addTxn(hub_messages_e txnIdentifier, void *txnData) {
    txnManager_s *mgr = &db.txnManager;

    std::lock_guard<std::mutex>lock(mgr->m);

    mgr->txnPending = true;
    mgr->firstTimeTxnCanBeCanceled = steady_clock::now() +
        kMinTransactionCancelTime;
    mgr->txnData = txnData;
    mgr->txnIdentifier = txnIdentifier;

    return 0;
}

// Only call this if you hold the db.txnManager.m lock.
static void closeTxnUnlocked() {
    txnManager_s *mgr = &db.txnManager;
    mgr->txnPending = false;
    free(mgr->txnData);
    mgr->txnData = nullptr;
}

static int closeTxn() {
    std::lock_guard<std::mutex>lock(db.txnManager.m);
    closeTxnUnlocked();
    return 0;
}

// If a transaction has been pending for longer than
// kMinTransactionCancelTime, this call will "cancel" that
// transaction and return that there are none pending.
static bool isTxnPending() {
    txnManager_s *mgr = &db.txnManager;
    std::lock_guard<std::mutex>lock(mgr->m);
    if (mgr->txnPending) {
        if (steady_clock::now() >= mgr->firstTimeTxnCanBeCanceled) {
            ALOGW("Transaction canceled");
            closeTxnUnlocked();
        }
    }
    return mgr->txnPending;
}

static int fetchTxnData(hub_messages_e *id, void **data) {
    txnManager_s *mgr = &db.txnManager;

    if (!id || !data) {
        ALOGW("Null params id %p, data %p", id, data);
        return -1;
    }

    std::lock_guard<std::mutex>lock(mgr->m);
    if (!mgr->txnPending) {
        ALOGW("No Transactions pending");
        return -1;
    }

    // else
    *id = mgr->txnIdentifier;
    *data = mgr->txnData;
    return 0;
}

int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
                         void *cookie);

const context_hub_t *get_hub_info(int hubHandle) {
    if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) {
        return &db.hubInfo.hubs[hubHandle];
    }
    return nullptr;
}

static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) {
    const context_hub_t *info = get_hub_info(hubHandle);

    if (info) {
        return db.hubInfo.contextHubModule->send_message(info->hub_id, msg);
    } else {
        ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
        return -1;
    }
}

static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) {
    const context_hub_t *info = get_hub_info(hubHandle);

    if (info) {
        msg->app_name = info->os_app_name;
        return 0;
    } else {
        ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
        return -1;
    }
}

static int get_hub_id_for_hub_handle(int hubHandle) {
    if (hubHandle < 0 || hubHandle >= db.hubInfo.numHubs) {
      return -1;
    } else {
      return db.hubInfo.hubs[hubHandle].hub_id;
    }
}

static int get_hub_handle_for_app_instance(jint id) {
    if (!db.appInstances.count(id)) {
        ALOGD("%s: Cannot find app for app instance %" PRId32,
              __FUNCTION__, id);
        return -1;
    }

    return db.appInstances[id].hubHandle;
}

static int get_hub_id_for_app_instance(jint id) {
    int hubHandle = get_hub_handle_for_app_instance(id);

    if (hubHandle < 0) {
        return -1;
    }

    return db.hubInfo.hubs[hubHandle].hub_id;
}

static jint get_app_instance_for_app_id(uint64_t app_id) {
    auto end = db.appInstances.end();
    for (auto current = db.appInstances.begin(); current != end; ++current) {
        if (current->second.appInfo.app_name.id == app_id) {
            return current->first;
        }
    }
    ALOGD("Cannot find app for app instance %" PRIu64 ".", app_id);
    return -1;
}

static int set_dest_app(hub_message_t *msg, jint id) {
    if (!db.appInstances.count(id)) {
        ALOGD("%s: Cannot find app for app instance %" PRId32,
              __FUNCTION__, id);
        return -1;
    }

    msg->app_name = db.appInstances[id].appInfo.app_name;
    return 0;
}

static void query_hub_for_apps(uint32_t hubHandle) {
    hub_message_t msg;
    query_apps_request_t queryMsg;

    // TODO(b/30835598): When we're able to tell which request our
    //     response matches, then we should allow this to be more
    //     targetted, instead of always being every app in the
    //     system.
    queryMsg.app_name.id = ALL_APPS;

    msg.message_type = CONTEXT_HUB_QUERY_APPS;
    msg.message_len  = sizeof(queryMsg);
    msg.message = &queryMsg;

    ALOGD("Sending query for apps to hub %" PRIu32, hubHandle);
    set_os_app_as_destination(&msg, hubHandle);
    if (send_msg_to_hub(&msg, hubHandle) != 0) {
        ALOGW("Could not query hub %" PRIu32 " for apps", hubHandle);
    }
}

static void sendQueryForApps() {
    for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
        query_hub_for_apps(i);
    }
}

static int return_id(jint id) {
    // Note : This method is not thread safe.
    // id returned is guaranteed to be in use
    if (id >= 0) {
        db.freeIds.push(id);
        return 0;
    }

    return -1;
}

static jint generate_id() {
    // Note : This method is not thread safe.
    jint retVal = -1;

    if (!db.freeIds.empty()) {
        retVal = db.freeIds.front();
        db.freeIds.pop();
    }

    return retVal;
}


static jint add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle,
        jint appInstanceHandle, JNIEnv *env) {
    // Not checking if the apps are indeed distinct
    app_instance_info_s entry;
    assert(appInfo);

    const char *action =
        (db.appInstances.count(appInstanceHandle) == 0) ? "Added" : "Updated";

    entry.appInfo = *appInfo;

    entry.instanceId = appInstanceHandle;
    entry.truncName = appInfo->app_name.id;
    entry.hubHandle = hubHandle;

    db.appInstances[appInstanceHandle] = entry;

    // Finally - let the service know of this app instance, to populate
    // the Java cache.
    env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceAddAppInstance,
                       hubHandle, entry.instanceId, entry.truncName,
                       entry.appInfo.version);

    ALOGI("%s App 0x%" PRIx64 " on hub Handle %" PRId32
          " as appInstance %" PRId32, action, entry.truncName,
          entry.hubHandle, appInstanceHandle);

    return appInstanceHandle;
}

int delete_app_instance(jint id, JNIEnv *env) {
    bool fullyDeleted = true;

    if (db.appInstances.count(id)) {
        db.appInstances.erase(id);
    } else {
        ALOGW("Cannot delete App id (%" PRId32 ") from the JNI C++ cache", id);
        fullyDeleted = false;
    }
    return_id(id);

    if ((env == nullptr) ||
        (env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceDeleteAppInstance,
                       id) != 0)) {
        ALOGW("Cannot delete App id (%" PRId32 ") from Java cache", id);
        fullyDeleted = false;
    }

    if (fullyDeleted) {
        ALOGI("Deleted App id : %" PRId32, id);
        return 0;
    }
    return -1;
}

static int startLoadAppTxn(uint64_t appId, int hubHandle) {
    app_instance_info_s *txnInfo = (app_instance_info_s *)malloc(sizeof(app_instance_info_s));
    jint instanceId = generate_id();

    if (!txnInfo || instanceId < 0) {
        return_id(instanceId);
        free(txnInfo);
        return -1;
    }

    txnInfo->truncName = appId;
    txnInfo->hubHandle = hubHandle;
    txnInfo->instanceId = instanceId;

    txnInfo->appInfo.app_name.id = appId;
    txnInfo->appInfo.num_mem_ranges = 0;
    txnInfo->appInfo.version = -1; // Awaited

    if (addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) {
        return_id(instanceId);
        free(txnInfo);
        return -1;
    }

    return 0;
}

static int startUnloadAppTxn(jint appInstanceHandle) {
    jint *txnData = (jint *) malloc(sizeof(jint));
    if (!txnData) {
        ALOGW("Cannot allocate memory to start unload transaction");
        return -1;
    }

    *txnData = appInstanceHandle;

    if (addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) {
        free(txnData);
        ALOGW("Cannot start transaction to unload app");
        return -1;
    }

    return 0;
}

static void initContextHubService() {
    int err = 0;
    db.hubInfo.hubs = nullptr;
    db.hubInfo.numHubs = 0;

    err = hw_get_module(CONTEXT_HUB_MODULE_ID,
                        (hw_module_t const**)(&db.hubInfo.contextHubModule));

    if (err) {
      ALOGE("** Could not load %s module : err %s", CONTEXT_HUB_MODULE_ID,
            strerror(-err));
    }

    // Prep for storing app info
    for (jint i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
        db.freeIds.push(i);
    }

    initTxnManager();
    if (db.hubInfo.contextHubModule) {
        int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
                                                                 &db.hubInfo.hubs);
        ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
        db.hubInfo.numHubs = retNumHubs;

        if (db.hubInfo.numHubs > 0) {
            db.hubInfo.numHubs = retNumHubs;
            db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs);

            if (!db.hubInfo.cookies) {
                ALOGW("Ran out of memory allocating cookies, bailing");
                return;
            }

            for (int i = 0; i < db.hubInfo.numHubs; i++) {
                db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
                ALOGI("Subscribing to hubHandle %d with OS App name %" PRIu64, i, db.hubInfo.hubs[i].os_app_name.id);
                if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
                                                                    context_hub_callback,
                                                                    &db.hubInfo.cookies[i]) == 0) {
                }
            }
        }

        sendQueryForApps();
    } else {
        ALOGW("No Context Hub Module present");
    }
}

static int onMessageReceipt(uint32_t *header, size_t headerLen, char *msg, size_t msgLen) {
    JNIEnv *env;

    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
      return -1;
    }

    jbyteArray jmsg = env->NewByteArray(msgLen);
    if (jmsg == nullptr) {
        ALOGW("Can't allocate %zu byte array", msgLen);
        return -1;
    }
    jintArray jheader = env->NewIntArray(headerLen);
    if (jheader == nullptr) {
        env->DeleteLocalRef(jmsg);
        ALOGW("Can't allocate %zu int array", headerLen);
        return -1;
    }

    env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
    env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);

    int ret = (env->CallIntMethod(db.jniInfo.jContextHubService,
                          db.jniInfo.contextHubServiceMsgReceiptCallback,
                          jheader, jmsg) != 0);
    env->DeleteLocalRef(jmsg);
    env->DeleteLocalRef(jheader);

    return ret;
}

int handle_query_apps_response(const uint8_t *msg, int msgLen,
                               uint32_t hubHandle) {
    JNIEnv *env;
    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
            return -1;
    }

    int numApps = msgLen / sizeof(hub_app_info);
    const hub_app_info *unalignedInfoAddr = (const hub_app_info*)msg;

    // We use this information to sync our JNI and Java caches of nanoapp info.
    // We want to accomplish two things here:
    // 1) Remove entries from our caches which are stale, and pertained to
    //    apps no longer running on Context Hub.
    // 2) Populate our caches with the latest information of all these apps.

    // We make a couple of assumptions here:
    // A) The JNI and Java caches are in sync with each other (this isn't
    //    necessarily true; any failure of a single call into Java land to
    //    update its cache will leave that cache in a bad state.  For NYC,
    //    we're willing to tolerate this for now).
    // B) The total number of apps is relatively small, so horribly inefficent
    //    algorithms aren't too painful.
    // C) We're going to call this relatively infrequently, so its inefficency
    //    isn't a big impact.


    // (1).  Looking for stale cache entries.  Yes, this is O(N^2).  See
    // assumption (B).  Per assumption (A), it is sufficient to iterate
    // over just the JNI cache.
    auto end = db.appInstances.end();
    for (auto current = db.appInstances.begin(); current != end; ) {
        app_instance_info_s cache_entry = current->second;
        // We perform our iteration here because if we call
        // delete_app_instance() below, it will erase() this entry.
        current++;
        bool entryIsStale = true;
        for (int i = 0; i < numApps; i++) {
            // We use memcmp since this could be unaligned.
            if (memcmp(&unalignedInfoAddr[i].app_name.id,
                       &cache_entry.appInfo.app_name.id,
                       sizeof(cache_entry.appInfo.app_name.id)) == 0) {
                // We found a match; this entry is current.
                entryIsStale = false;
                break;
            }
        }
        if (entryIsStale) {
            delete_app_instance(cache_entry.instanceId, env);
        }
    }

    // (2).  Update our caches with the latest.
    for (int i = 0; i < numApps; i++) {
        hub_app_info query_info;
        memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
        // We will only have one instance of the app
        // TODO : Change this logic once we support multiple instances of the same app
        jint appInstance = get_app_instance_for_app_id(query_info.app_name.id);
        if (appInstance == -1) {
            // This is a previously unknown app, let's allocate an "id" for it.
            appInstance = generate_id();
        }
        add_app_instance(&query_info, hubHandle, appInstance, env);
    }

    return 0;
}

// TODO(b/30807327): Do not use raw bytes for additional data.  Use the
//     JNI interfaces for the appropriate types.
static void passOnOsResponse(uint32_t hubHandle, uint32_t msgType,
                             status_response_t *rsp, int8_t *additionalData,
                             size_t additionalDataLen) {
    JNIEnv *env;

    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
        ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32, msgType);
        return;
    }

    uint32_t header[MSG_HEADER_SIZE];
    memset(header, 0, sizeof(header));

    if (!additionalData) {
        additionalDataLen = 0; // clamp
    }
    int msgLen = 1 + additionalDataLen;

    int8_t *msg = new int8_t[msgLen];

    if (!msg) {
        ALOGW("Unexpected : Ran out of memory, cannot send response");
        return;
    }

    header[HEADER_FIELD_MSG_TYPE] = msgType;
    header[HEADER_FIELD_MSG_VERSION] = 0;
    header[HEADER_FIELD_HUB_HANDLE] = hubHandle;
    header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID;

    // Due to API constraints, at the moment we can't change the fact that
    // we're changing our 4-byte response to a 1-byte value.  But we can prevent
    // the possible change in sign (and thus meaning) that would happen from
    // a naive cast.  Further, we can log when we're losing part of the value.
    // TODO(b/30918279): Don't truncate this result.
    int8_t truncatedResult;
    bool neededToTruncate;
    if (rsp->result < INT8_MIN) {
        neededToTruncate = true;
        truncatedResult = INT8_MIN;
    } else if (rsp->result > INT8_MAX) {
        neededToTruncate = true;
        truncatedResult = INT8_MAX;
    } else {
        neededToTruncate = false;
        // Since this value fits within an int8_t, this is a safe cast which
        // won't change the value or sign.
        truncatedResult = static_cast<int8_t>(rsp->result);
    }
    if (neededToTruncate) {
        ALOGW("Response from Context Hub truncated.  Value was %" PRId32
              ", but giving Java layer %" PRId8,
              rsp->result, (int)truncatedResult);
    }

    msg[0] = truncatedResult;

    if (additionalData) {
        memcpy(&msg[1], additionalData, additionalDataLen);
    }

    jbyteArray jmsg = env->NewByteArray(msgLen);
    jintArray jheader = env->NewIntArray(sizeof(header));

    env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
    env->SetIntArrayRegion(jheader, 0, sizeof(header), (jint *)header);

    ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32,
          header[HEADER_FIELD_MSG_TYPE], header[HEADER_FIELD_APP_INSTANCE],
          header[HEADER_FIELD_HUB_HANDLE]);

    env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceMsgReceiptCallback,
                       jheader, jmsg);
    env->DeleteLocalRef(jmsg);
    env->DeleteLocalRef(jheader);

    delete[] msg;
}

void closeUnloadTxn(bool success) {
    void *txnData = nullptr;
    hub_messages_e txnId;

    if (success && fetchTxnData(&txnId, &txnData) == 0 &&
        txnId == CONTEXT_HUB_UNLOAD_APP) {
        JNIEnv *env;
        if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
            ALOGW("Could not attach to JVM !");
            env = nullptr;
        }
        jint handle = *reinterpret_cast<jint *>(txnData);
        delete_app_instance(handle, env);
    } else {
        ALOGW("Could not unload the app successfully ! success %d, txnData %p", success, txnData);
    }

    closeTxn();
}

static bool closeLoadTxn(bool success, jint *appInstanceHandle) {
    void *txnData;
    hub_messages_e txnId;

    if (success && fetchTxnData(&txnId, &txnData) == 0 &&
        txnId == CONTEXT_HUB_LOAD_APP) {
        app_instance_info_s *info = (app_instance_info_s *)txnData;
        *appInstanceHandle = info->instanceId;

        JNIEnv *env;
        if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) {
            add_app_instance(&info->appInfo, info->hubHandle, info->instanceId, env);
        } else {
            ALOGW("Could not attach to JVM !");
            success = false;
        }
        // While we just called add_app_instance above, our info->appInfo was
        // incomplete (for example, the 'version' is hardcoded to -1).  So we
        // trigger an additional query to the CHRE, so we'll be able to get
        // all the app "info", and have our JNI and Java caches with the
        // full information.
        sendQueryForApps();
    } else {
        ALOGW("Could not load the app successfully ! Unexpected failure");
        *appInstanceHandle = INVALID_APP_ID;
        success = false;
    }

    closeTxn();
    return success;
}

static bool isValidOsStatus(const uint8_t *msg, size_t msgLen,
                            status_response_t *rsp) {
    // Workaround a bug in some HALs
    if (msgLen == 1) {
        rsp->result = msg[0];
        return true;
    }

    if (!msg || msgLen != sizeof(*rsp)) {
        ALOGW("Received invalid response %p of size %zu", msg, msgLen);
        return false;
    }

    memcpy(rsp, msg, sizeof(*rsp));

    // No sanity checks on return values
    return true;
}

static int handle_os_message(uint32_t msgType, uint32_t hubHandle,
                             const uint8_t *msg, int msgLen) {
    int retVal = -1;

    ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d",
          hubHandle, msgType, msgLen);

    struct status_response_t rsp;

    switch(msgType) {

      case CONTEXT_HUB_APPS_ENABLE:
      case CONTEXT_HUB_APPS_DISABLE:
      case CONTEXT_HUB_LOAD_APP:
      case CONTEXT_HUB_UNLOAD_APP:
          if (isValidOsStatus(msg, msgLen, &rsp)) {
              if (msgType == CONTEXT_HUB_LOAD_APP) {
                  jint appInstanceHandle = INVALID_APP_ID;
                  bool appRunningOnHub = (rsp.result == 0);
                  if (!(closeLoadTxn(appRunningOnHub, &appInstanceHandle))) {
                      if (appRunningOnHub) {
                          // Now we're in an odd situation.  Our nanoapp
                          // is up and running on the Context Hub.  However,
                          // something went wrong in our Service code so that
                          // we're not able to properly track this nanoapp
                          // in our Service code.  If we tell the Java layer
                          // things are good, it's a lie because the handle
                          // we give them will fail when used with the Service.
                          // If we tell the Java layer this failed, it's kind
                          // of a lie as well, since this nanoapp is running.
                          //
                          // We leave a more robust fix for later, and for
                          // now just tell the user things have failed.
                          //
                          // TODO(b/30835981): Make this situation better.
                          rsp.result = -1;
                      }
                  }
                  passOnOsResponse(hubHandle, msgType, &rsp, (int8_t *)(&appInstanceHandle),
                                   sizeof(appInstanceHandle));
              } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
                  closeUnloadTxn(rsp.result == 0);
                  passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
              } else {
                  passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
              }
              retVal = 0;
          }
          break;

      case CONTEXT_HUB_QUERY_APPS:
          rsp.result = 0;
          retVal = handle_query_apps_response(msg, msgLen, hubHandle);
          passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
          break;

      case CONTEXT_HUB_QUERY_MEMORY:
          // Deferring this use
          retVal = 0;
          break;

      case CONTEXT_HUB_OS_REBOOT:
          if (isValidOsStatus(msg, msgLen, &rsp)) {
              rsp.result = 0;
              ALOGW("Context Hub handle %d restarted", hubHandle);
              closeTxn();
              passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
              query_hub_for_apps(hubHandle);
              retVal = 0;
          }
          break;

      default:
          retVal = -1;
          break;
    }

    return retVal;
}

static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
    int *ptr = (int *)cookie;

    if (!ptr || *ptr >= db.hubInfo.numHubs) {
        return false;
    }

    if (db.hubInfo.hubs[*ptr].hub_id != hub_id) {
        return false;
    } else {
        return true;
    }
}


int context_hub_callback(uint32_t hubId,
                         const struct hub_message_t *msg,
                         void *cookie) {
    if (!msg) {
        ALOGW("NULL message");
        return -1;
    }
    if (!sanity_check_cookie(cookie, hubId)) {
        ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
              hubId, cookie);

        return -1;
    }


    uint32_t messageType = msg->message_type;
    uint32_t hubHandle = *(uint32_t*) cookie;

    if (messageType < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
        handle_os_message(messageType, hubHandle, (uint8_t*) msg->message, msg->message_len);
    } else {
        jint appHandle = get_app_instance_for_app_id(msg->app_name.id);
        if (appHandle < 0) {
            ALOGE("Filtering out message due to invalid App Instance.");
        } else {
            uint32_t msgHeader[MSG_HEADER_SIZE] = {};
            msgHeader[HEADER_FIELD_MSG_TYPE] = messageType;
            msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle;
            msgHeader[HEADER_FIELD_APP_INSTANCE] = appHandle;
            onMessageReceipt(msgHeader, MSG_HEADER_SIZE, (char*) msg->message, msg->message_len);
        }
    }

    return 0;
}

static int init_jni(JNIEnv *env, jobject instance) {

    if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
        return -1;
    }

    db.jniInfo.jContextHubService = env->NewGlobalRef(instance);

    db.jniInfo.contextHubInfoClass =
            env->FindClass("android/hardware/location/ContextHubInfo");

    db.jniInfo.contextHubServiceClass =
            env->FindClass("android/hardware/location/ContextHubService");

    db.jniInfo.memoryRegionsClass =
            env->FindClass("android/hardware/location/MemoryRegion");

    db.jniInfo.contextHubInfoCtor =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
    db.jniInfo.contextHubInfoSetId =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V");
    db.jniInfo.contextHubInfoSetName =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
                                "(Ljava/lang/String;)V");

    db.jniInfo.contextHubInfoSetVendor =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setVendor", "(Ljava/lang/String;)V");
    db.jniInfo.contextHubInfoSetToolchain =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setToolchain", "(Ljava/lang/String;)V");
    db.jniInfo.contextHubInfoSetPlatformVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setPlatformVersion", "(I)V");
    db.jniInfo.contextHubInfoSetStaticSwVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setStaticSwVersion", "(I)V");
    db.jniInfo.contextHubInfoSetToolchainVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setToolchainVersion", "(I)V");
    db.jniInfo.contextHubInfoSetPeakMips =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setPeakMips", "(F)V");
    db.jniInfo.contextHubInfoSetStoppedPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setStoppedPowerDrawMw", "(F)V");
    db.jniInfo.contextHubInfoSetSleepPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setSleepPowerDrawMw", "(F)V");
    db.jniInfo.contextHubInfoSetPeakPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setPeakPowerDrawMw", "(F)V");
    db.jniInfo.contextHubInfoSetSupportedSensors =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setSupportedSensors", "([I)V");
    db.jniInfo.contextHubInfoSetMemoryRegions =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
    db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
             env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                "setMaxPacketLenBytes", "(I)V");


    db.jniInfo.contextHubServiceMsgReceiptCallback =
            env->GetMethodID(db.jniInfo.contextHubServiceClass, "onMessageReceipt",
                               "([I[B)I");
    db.jniInfo.contextHubInfoSetName =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
            "(Ljava/lang/String;)V");

    db.jniInfo.contextHubServiceAddAppInstance =
                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
                                    "addAppInstance", "(IIJI)I");

    db.jniInfo.contextHubServiceDeleteAppInstance =
                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
                                    "deleteAppInstance", "(I)I");

    return 0;
}

static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t *hub) {
    jstring jstrBuf;
    jintArray jintBuf;
    jobjectArray jmemBuf;

    jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass,
                                  db.jniInfo.contextHubInfoCtor);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id);

    jstrBuf = env->NewStringUTF(hub->name);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    jstrBuf = env->NewStringUTF(hub->vendor);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    jstrBuf = env->NewStringUTF(hub->toolchain);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw,
                        hub->stopped_power_draw_mw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw,
                        hub->sleep_power_draw_mw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw,
                        hub->peak_power_draw_mw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
                        hub->max_supported_msg_len);


    jintBuf = env->NewIntArray(hub->num_connected_sensors);
    int *connectedSensors = new int[hub->num_connected_sensors];

    if (!connectedSensors) {
      ALOGW("Cannot allocate memory! Unexpected");
      assert(false);
    } else {
      for (unsigned int i = 0; i < hub->num_connected_sensors; i++) {
        connectedSensors[i] = hub->connected_sensors[i].sensor_id;
      }
    }

    env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
                           connectedSensors);

    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf);
    env->DeleteLocalRef(jintBuf);

    // We are not getting the memory regions from the CH Hal - change this when it is available
    jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
    // Note the zero size above. We do not need to set any elements
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
    env->DeleteLocalRef(jmemBuf);


    delete[] connectedSensors;
    return jHub;
}

static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
{
    jobject hub;
    jobjectArray retArray;

    if (init_jni(env, instance) < 0) {
        return nullptr;
    }

    initContextHubService();

    if (db.hubInfo.numHubs > 1) {
      ALOGW("Clamping the number of hubs to 1");
      db.hubInfo.numHubs = 1;
    }

    retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);

    for(int i = 0; i < db.hubInfo.numHubs; i++) {
        hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
        env->SetObjectArrayElement(retArray, i, hub);
    }

    return retArray;
}

static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
                              jbyteArray data_) {
    jint retVal = -1; // Default to failure

    jint *header = env->GetIntArrayElements(header_, 0);
    unsigned int numHeaderElements = env->GetArrayLength(header_);
    jbyte *data = env->GetByteArrayElements(data_, 0);
    int dataBufferLength = env->GetArrayLength(data_);

    if (numHeaderElements < MSG_HEADER_SIZE) {
        ALOGW("Malformed header len");
        return -1;
    }

    uint32_t appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE];
    uint32_t msgType = header[HEADER_FIELD_MSG_TYPE];
    int hubHandle = -1;
    int hubId;
    uint64_t appId;

    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
        hubHandle = get_hub_handle_for_app_instance(appInstanceHandle);
    } else if (msgType == CONTEXT_HUB_LOAD_APP) {
        if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) {
            return -1;
        }
        uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO];
        uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI];
        appId = appIdHi << 32 | appIdLo;

        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
    } else {
        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
    }

    if (hubHandle < 0) {
        ALOGD("Invalid hub Handle %d", hubHandle);
        return -1;
    }

    if (msgType == CONTEXT_HUB_LOAD_APP ||
        msgType == CONTEXT_HUB_UNLOAD_APP) {

        if (isTxnPending()) {
            ALOGW("Cannot load or unload app while a transaction is pending !");
            return -1;
        }

        if (msgType == CONTEXT_HUB_LOAD_APP) {
            if (startLoadAppTxn(appId, hubHandle) != 0) {
                ALOGW("Cannot Start Load Transaction");
                return -1;
            }
        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
            if (startUnloadAppTxn(appInstanceHandle) != 0) {
                ALOGW("Cannot Start UnLoad Transaction");
                return -1;
            }
        }
    }

    bool setAddressSuccess = false;
    hub_message_t msg;

    msg.message_type = msgType;

    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
        msg.message_len = sizeof(db.appInstances[appInstanceHandle].appInfo.app_name);
        msg.message = &db.appInstances[appInstanceHandle].appInfo.app_name;
        setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0);
        hubId = get_hub_id_for_hub_handle(hubHandle);
    } else {
        msg.message_len = dataBufferLength;
        msg.message = data;

        if (header[HEADER_FIELD_APP_INSTANCE] == OS_APP_ID) {
            setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0);
            hubId = get_hub_id_for_hub_handle(hubHandle);
        } else {
            setAddressSuccess = (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0);
            hubId = get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]);
        }
    }

    if (setAddressSuccess && hubId >= 0) {
        ALOGD("Asking HAL to remove app");
        retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg);
    } else {
      ALOGD("Could not find app instance %" PRId32 " on hubHandle %" PRId32
            ", setAddress %d",
            header[HEADER_FIELD_APP_INSTANCE],
            header[HEADER_FIELD_HUB_HANDLE],
            (int)setAddressSuccess);
    }

    if (retVal != 0) {
        ALOGD("Send Message failure - %d", retVal);
        if (msgType == CONTEXT_HUB_LOAD_APP) {
            jint ignored;
            closeLoadTxn(false, &ignored);
        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
            closeUnloadTxn(false);
        }
    }

    env->ReleaseIntArrayElements(header_, header, 0);
    env->ReleaseByteArrayElements(data_, data, 0);

    return retVal;
}

//--------------------------------------------------------------------------------------------------
//
static const JNINativeMethod gContextHubServiceMethods[] = {
    {"nativeInitialize",
             "()[Landroid/hardware/location/ContextHubInfo;",
             (void*)nativeInitialize },
    {"nativeSendMessage",
            "([I[B)I",
            (void*)nativeSendMessage }
};

}//namespace android

using namespace android;

int register_android_hardware_location_ContextHubService(JNIEnv *env)
{
    RegisterMethodsOrDie(env, "android/hardware/location/ContextHubService",
            gContextHubServiceMethods, NELEM(gContextHubServiceMethods));

    return 0;
}
