/*
 * Copyright (C) 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 "Contexthub.h"

#include <inttypes.h>

#include <log/log.h>

#include <android/hardware/contexthub/1.0/IContexthub.h>
#include <hardware/context_hub.h>
#include <sys/endian.h>

#undef LOG_TAG
#define LOG_TAG "ContextHubHalAdapter"

namespace android {
namespace hardware {
namespace contexthub {
namespace V1_0 {
namespace implementation {

static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);

Contexthub::Contexthub()
        : mInitCheck(NO_INIT),
          mContextHubModule(nullptr),
          mDeathRecipient(new DeathRecipient(this)),
          mIsTransactionPending(false) {
    const hw_module_t *module;

    mInitCheck = hw_get_module(CONTEXT_HUB_MODULE_ID, &module);

    if (mInitCheck != OK) {
        ALOGE("Could not load %s module: %s", CONTEXT_HUB_MODULE_ID, strerror(-mInitCheck));
    } else if (module == nullptr) {
        ALOGE("hal returned succes but a null module!");
        // Assign an error, this should not really happen...
        mInitCheck = UNKNOWN_ERROR;
    } else {
        ALOGI("Loaded Context Hub module");
        mContextHubModule = reinterpret_cast<const context_hub_module_t *>(module);
    }
}

bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) {
    if (!isValidHubId(hubId)) {
        ALOGW("%s: Hub information is null for hubHandle %d",
              __FUNCTION__,
              hubId);
        return false;
    } else {
        msg->app_name = mCachedHubInfo[hubId].osAppName;
        return true;
    }
}

Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
    std::vector<ContextHub> hubs;
    if (isInitialized()) {
        const context_hub_t *hubArray = nullptr;
        size_t numHubs;

        // Explicitly discarding const. HAL method discards it.
        numHubs = mContextHubModule->get_hubs(const_cast<context_hub_module_t *>(mContextHubModule),
                                              &hubArray);
        ALOGI("Context Hub Hal Adapter reports %zu hubs", numHubs);

        mCachedHubInfo.clear();

        for (size_t i = 0; i < numHubs; i++) {
            CachedHubInformation info;
            ContextHub c;

            c.hubId = hubArray[i].hub_id;
            c.name = hubArray[i].name;
            c.vendor = hubArray[i].vendor;
            c.toolchain = hubArray[i].toolchain;
            c.toolchainVersion = hubArray[i].toolchain_version;
            c.platformVersion = hubArray[i].platform_version;
            c.maxSupportedMsgLen = hubArray[i].max_supported_msg_len;
            c.peakMips = hubArray[i].peak_mips;
            c.peakPowerDrawMw = hubArray[i].peak_power_draw_mw;
            c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw;
            c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw;

            info.callback = nullptr;
            info.osAppName = hubArray[i].os_app_name;
            mCachedHubInfo[hubArray[i].hub_id] = info;

            hubs.push_back(c);
        }
    } else {
        ALOGW("Context Hub Hal Adapter not initialized");
    }

    _hidl_cb(hubs);
    return Void();
}

Contexthub::DeathRecipient::DeathRecipient(sp<Contexthub> contexthub)
        : mContexthub(contexthub) {}

void Contexthub::DeathRecipient::serviceDied(
        uint64_t cookie,
        const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
    uint32_t hubId = static_cast<uint32_t>(cookie);
    mContexthub->handleServiceDeath(hubId);
}

bool Contexthub::isValidHubId(uint32_t hubId) {
    if (!mCachedHubInfo.count(hubId)) {
        ALOGW("Hub information not found for hubId %" PRIu32, hubId);
        return false;
    } else {
        return true;
    }
}

sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
    if (!isValidHubId(hubId)) {
        return nullptr;
    } else {
        return mCachedHubInfo[hubId].callback;
    }
}

Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
                                            const ContextHubMsg &msg) {
    if (!isInitialized()) {
        return Result::NOT_INIT;
    }

    if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) {
        return Result::BAD_PARAMS;
    }

    hub_message_t txMsg = {
        .app_name.id = msg.appName,
        .message_type = msg.msgType,
        .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above
        .message = static_cast<const uint8_t *>(msg.msg.data()),
    };

    // Use a dummy to prevent send_message with empty message from failing prematurely
    static uint8_t dummy;
    if (txMsg.message_len == 0 && txMsg.message == nullptr) {
        txMsg.message = &dummy;
    }

    ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64,
          txMsg.message_type,
          txMsg.message_len,
          txMsg.app_name.id);

    if(mContextHubModule->send_message(hubId, &txMsg) != 0) {
        return Result::TRANSACTION_FAILED;
    }

    return Result::OK;
}

Return<Result> Contexthub::reboot(uint32_t hubId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    hub_message_t msg;

    if (setOsAppAsDestination(&msg, hubId) == false) {
        return Result::BAD_PARAMS;
    }

    msg.message_type = CONTEXT_HUB_OS_REBOOT;
    msg.message_len = 0;
    msg.message = nullptr;

    if(mContextHubModule->send_message(hubId, &msg) != 0) {
        return Result::TRANSACTION_FAILED;
    } else {
        return Result::OK;
    }
}

Return<Result> Contexthub::registerCallback(uint32_t hubId,
                                            const sp<IContexthubCallback> &cb) {
    Return<Result> retVal = Result::BAD_PARAMS;

    if (!isInitialized()) {
        // Not initilalized
        ALOGW("Context hub not initialized successfully");
        retVal = Result::NOT_INIT;
    } else if (!isValidHubId(hubId)) {
        // Initialized, but hubId is  not valid
        retVal = Result::BAD_PARAMS;
    } else if (mContextHubModule->subscribe_messages(hubId,
                                                     contextHubCb,
                                                     this) == 0) {
        // Initialized && valid hub && subscription successful
        if (mCachedHubInfo[hubId].callback != nullptr) {
            ALOGD("Modifying callback for hubId %" PRIu32, hubId);
            mCachedHubInfo[hubId].callback->unlinkToDeath(mDeathRecipient);
        }

        mCachedHubInfo[hubId].callback = cb;
        if (cb != nullptr) {
            Return<bool> linkResult = cb->linkToDeath(mDeathRecipient, hubId);
            bool linkSuccess = linkResult.isOk() ?
                static_cast<bool>(linkResult) : false;
            if (!linkSuccess) {
                ALOGW("Couldn't link death recipient for hubId %" PRIu32,
                      hubId);
            }
        }
        retVal = Result::OK;
    } else {
        // Initalized && valid hubId - but subscription unsuccessful
        // This is likely an internal error in the HAL implementation, but we
        // cannot add more information.
        ALOGW("Could not subscribe to the hub for callback");
        retVal = Result::UNKNOWN_FAILURE;
    }

    return retVal;
}

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 == nullptr || msgLen != sizeof(*rsp)) {
        ALOGI("Received invalid response (is null : %d, size %zu)",
              msg == nullptr ? 1 : 0,
              msgLen);
        return false;
    }

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

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

int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
                                uint32_t msgType,
                                const uint8_t *msg,
                                int msgLen) {
    int retVal = -1;


    switch(msgType) {
        case CONTEXT_HUB_APPS_ENABLE:
        case CONTEXT_HUB_APPS_DISABLE:
        case CONTEXT_HUB_LOAD_APP:
        case CONTEXT_HUB_UNLOAD_APP:
        {
            struct status_response_t rsp;
            TransactionResult result;
            if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) {
                retVal = 0;
                result = TransactionResult::SUCCESS;
            } else {
                result = TransactionResult::FAILURE;
            }

            mIsTransactionPending = false;
            if (cb != nullptr) {
                cb->handleTxnResult(mTransactionId, result);
            }
            retVal = 0;
            break;
        }

        case CONTEXT_HUB_QUERY_APPS:
        {
            std::vector<HubAppInfo> apps;
            int numApps = msgLen / sizeof(hub_app_info);
            const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg);

            for (int i = 0; i < numApps; i++) {
                hub_app_info query_info;
                memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
                HubAppInfo app;
                app.appId = query_info.app_name.id;
                app.version = query_info.version;
                // TODO :: Add memory ranges

                apps.push_back(app);
            }

            if (cb != nullptr) {
                cb->handleAppsInfo(apps);
            }
            retVal = 0;
            break;
        }

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

        case CONTEXT_HUB_OS_REBOOT:
        {
            mIsTransactionPending = false;
            if (cb != nullptr) {
                cb->handleHubEvent(AsyncEventType::RESTARTED);
            }
            retVal = 0;
            break;
        }

        default:
        {
            retVal = -1;
            break;
        }
      }

      return retVal;
}

void Contexthub::handleServiceDeath(uint32_t hubId) {
    ALOGI("Callback/service died for hubId %" PRIu32, hubId);
    int ret = mContextHubModule->subscribe_messages(hubId, nullptr, nullptr);
    if (ret != 0) {
        ALOGW("Failed to unregister callback from hubId %" PRIu32 ": %d",
              hubId, ret);
    }
    mCachedHubInfo[hubId].callback.clear();
}

int Contexthub::contextHubCb(uint32_t hubId,
                             const struct hub_message_t *rxMsg,
                             void *cookie) {
    Contexthub *obj = static_cast<Contexthub *>(cookie);

    if (rxMsg == nullptr) {
        ALOGW("Ignoring NULL message");
        return -1;
    }

    if (!obj->isValidHubId(hubId)) {
        ALOGW("Invalid hub Id %" PRIu32, hubId);
        return -1;
    }

    sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId);

    if (cb == nullptr) {
        // This should not ever happen
        ALOGW("No callback registered, returning");
        return -1;
    }

    if (rxMsg->message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
        obj->handleOsMessage(cb,
                             rxMsg->message_type,
                             static_cast<const uint8_t *>(rxMsg->message),
                             rxMsg->message_len);
    } else {
        ContextHubMsg msg;

        msg.appName = rxMsg->app_name.id;
        msg.msgType = rxMsg->message_type;
        msg.hostEndPoint = static_cast<uint16_t>(HostEndPoint::BROADCAST);
        msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg->message),
                                       static_cast<const uint8_t *>(rxMsg->message) +
                                       rxMsg->message_len);

        cb->handleClientMsg(msg);
    }

    return 0;
}

Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
                                         uint64_t appId,
                                         uint32_t transactionId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    if (mIsTransactionPending) {
        return Result::TRANSACTION_PENDING;
    }

    hub_message_t msg;

    if (setOsAppAsDestination(&msg, hubId) == false) {
        return Result::BAD_PARAMS;
    }

    struct apps_disable_request_t req;

    msg.message_type = CONTEXT_HUB_UNLOAD_APP;
    msg.message_len = sizeof(req);
    msg.message = &req;
    req.app_name.id = appId;

    if(mContextHubModule->send_message(hubId, &msg) != 0) {
        return Result::TRANSACTION_FAILED;
    } else {
        mTransactionId = transactionId;
        mIsTransactionPending = true;
        return Result::OK;
    }
}

Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
                                       const NanoAppBinary& appBinary,
                                       uint32_t transactionId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    if (mIsTransactionPending) {
        return Result::TRANSACTION_PENDING;
    }

    hub_message_t hubMsg;

    if (setOsAppAsDestination(&hubMsg, hubId) == false) {
        return Result::BAD_PARAMS;
    }

    // Data from the nanoapp header is passed through HIDL as explicit fields,
    // but the legacy HAL expects it prepended to the binary, therefore we must
    // reconstruct it here prior to passing to the legacy HAL.
    const struct nano_app_binary_t header = {
        .header_version = htole32(1),
        .magic = htole32(NANOAPP_MAGIC),
        .app_id.id = htole64(appBinary.appId),
        .app_version = htole32(appBinary.appVersion),
        .flags = htole32(appBinary.flags),
        .hw_hub_type = htole64(0),
        .target_chre_api_major_version = appBinary.targetChreApiMajorVersion,
        .target_chre_api_minor_version = appBinary.targetChreApiMinorVersion,
    };
    const uint8_t *headerBytes = reinterpret_cast<const uint8_t *>(&header);

    std::vector<uint8_t> binaryWithHeader(appBinary.customBinary);
    binaryWithHeader.insert(binaryWithHeader.begin(),
                            headerBytes,
                            headerBytes + sizeof(header));

    hubMsg.message_type = CONTEXT_HUB_LOAD_APP;
    hubMsg.message_len = binaryWithHeader.size();
    hubMsg.message = binaryWithHeader.data();

    if (mContextHubModule->send_message(hubId, &hubMsg) != 0) {
        return Result::TRANSACTION_FAILED;
    } else {
        mTransactionId = transactionId;
        mIsTransactionPending = true;
        return Result::OK;
    }
}

Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
                                         uint64_t appId,
                                         uint32_t transactionId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    if (mIsTransactionPending) {
        return Result::TRANSACTION_PENDING;
    }

    hub_message_t msg;

    if (setOsAppAsDestination(&msg, hubId) == false) {
        return Result::BAD_PARAMS;
    }

    struct apps_enable_request_t req;

    msg.message_type = CONTEXT_HUB_APPS_ENABLE;
    msg.message_len = sizeof(req);
    req.app_name.id = appId;
    msg.message = &req;

    if(mContextHubModule->send_message(hubId, &msg) != 0) {
        return Result::TRANSACTION_FAILED;
    } else {
        mTransactionId = transactionId;
        mIsTransactionPending = true;
        return Result::OK;
    }
}

Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
                                          uint64_t appId,
                                          uint32_t transactionId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    if (mIsTransactionPending) {
        return Result::TRANSACTION_PENDING;
    }

    hub_message_t msg;

    if (setOsAppAsDestination(&msg, hubId) == false) {
        return Result::BAD_PARAMS;
    }

    struct apps_disable_request_t req;

    msg.message_type = CONTEXT_HUB_APPS_DISABLE;
    msg.message_len = sizeof(req);
    req.app_name.id = appId;
    msg.message = &req;

    if(mContextHubModule->send_message(hubId, &msg) != 0) {
        return Result::TRANSACTION_FAILED;
    } else {
        mTransactionId = transactionId;
        mIsTransactionPending = true;
        return Result::OK;
    }
}

Return<Result> Contexthub::queryApps(uint32_t hubId) {
    if (!isInitialized()) {
      return Result::NOT_INIT;
    }

    hub_message_t msg;

    if (setOsAppAsDestination(&msg, hubId) == false) {
        ALOGW("Could not find hubId %" PRIu32, hubId);
        return Result::BAD_PARAMS;
    }

    query_apps_request_t payload;
    payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter
    msg.message = &payload;
    msg.message_len = sizeof(payload);
    msg.message_type = CONTEXT_HUB_QUERY_APPS;

    if(mContextHubModule->send_message(hubId, &msg) != 0) {
        ALOGW("Query Apps sendMessage failed");
        return Result::TRANSACTION_FAILED;
    }

    return Result::OK;
}

bool Contexthub::isInitialized() {
    return (mInitCheck == OK && mContextHubModule != nullptr);
}

IContexthub *HIDL_FETCH_IContexthub(const char * halName) {
    ALOGI("%s Called for %s", __FUNCTION__, halName);
    Contexthub *contexthub = new Contexthub;

    if (!contexthub->isInitialized()) {
        delete contexthub;
        contexthub = nullptr;
    }

    return contexthub;
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace contexthub
}  // namespace hardware
}  // namespace android
