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

#define LOG_TAG "NanohubHAL"

#include <cassert>
#include <cerrno>
#include <cinttypes>

#include <endian.h>

#include <vector>

#include <utils/Log.h>

#include <endian.h>

#include <hardware/context_hub.h>
#include "nanohub_perdevice.h"
#include "system_comms.h"
#include "nanohubhal.h"

namespace android {

namespace nanohub {

static void readAppName(MessageBuf &buf, hub_app_name_t &name) {
    name.id = buf.readU64();
}

static void writeAppName(MessageBuf &buf, const hub_app_name_t &name) {
    buf.writeU64(name.id);
}

static void readNanohubAppInfo(MessageBuf &buf, NanohubAppInfo &info) {
    size_t pos = buf.getPos();
    readAppName(buf, info.name);
    info.version = buf.readU32();
    info.flashUse = buf.readU32();
    info.ramUse = buf.readU32();
    if ((buf.getPos() - pos) != sizeof(info)) {
        ALOGE("%s: failed to read object", __func__);
    }
}

static void readNanohubMemInfo(MessageBuf &buf,  NanohubMemInfo &mi) {
    size_t pos = buf.getPos();
    mi.flashSz = buf.readU32();
    mi.blSz = buf.readU32();
    mi.osSz = buf.readU32();
    mi.sharedSz = buf.readU32();
    mi.eeSz = buf.readU32();
    mi.ramSz = buf.readU32();

    mi.blUse = buf.readU32();
    mi.osUse = buf.readU32();
    mi.sharedUse = buf.readU32();
    mi.eeUse = buf.readU32();
    mi.ramUse = buf.readU32();
    if ((buf.getPos() - pos) != sizeof(mi)) {
        ALOGE("%s: failed to read object", __func__);
    }
}

NanohubRsp::NanohubRsp(MessageBuf &buf, bool no_status) {
    // all responses start with command
    // most of them have 4-byte status (result code)
    cmd = buf.readU8();
    if (!buf.getSize()) {
        status = -EINVAL;
    } else if (no_status) {
        status = 0;
    } else {
        status = buf.readU32();
    }
}

int SystemComm::sendToSystem(const void *data, size_t len) {
    if (NanoHub::messageTracingEnabled()) {
        dumpBuffer("HAL -> SYS", getSystem()->mHostIfAppName, 0, data, len);
    }
    return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len);
}

int SystemComm::AppInfoSession::setup(const hub_message_t *) {
    Mutex::Autolock _l(mLock);
    int suggestedSize = mAppInfo.size() ? mAppInfo.size() : 20;

    mAppInfo.clear();
    mAppInfo.reserve(suggestedSize);
    setState(SESSION_USER);

    return requestNext();
}

inline hub_app_name_t deviceAppNameToHost(const hub_app_name_t src) {
    hub_app_name_t res = { .id = le64toh(src.id) };
    return res;
}

inline hub_app_name_t hostAppNameToDevice(const hub_app_name_t src) {
    hub_app_name_t res = { .id = htole64(src.id) };
    return res;
}

int SystemComm::AppInfoSession::handleRx(MessageBuf &buf)
{
    Mutex::Autolock _l(mLock);

    NanohubRsp rsp(buf, true);
    if (rsp.cmd != NANOHUB_QUERY_APPS) {
        return 1;
    }
    size_t len = buf.getRoom();
    if (len != sizeof(NanohubAppInfo) && len) {
        ALOGE("%s: Invalid data size; have %zu, need %zu", __func__,
              len, sizeof(NanohubAppInfo));
        return -EINVAL;
    }
    if (getState() != SESSION_USER) {
        ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
        return -EINVAL;
    }
    if (len) {
        NanohubAppInfo info;
        readNanohubAppInfo(buf, info);
        hub_app_info appInfo;
        appInfo.num_mem_ranges = 0;
        if (info.flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
            mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
            range.type = HUB_MEM_TYPE_MAIN;
            range.total_bytes = info.flashUse;
        }
        if (info.ramUse != NANOHUB_MEM_SZ_UNKNOWN) {
            mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
            range.type = HUB_MEM_TYPE_RAM;
            range.total_bytes = info.ramUse;
        }

        appInfo.app_name = info.name;
        appInfo.version = info.version;

        mAppInfo.push_back(appInfo);
        return requestNext();
    } else {
        sendToApp(CONTEXT_HUB_QUERY_APPS,
                        static_cast<const void *>(mAppInfo.data()),
                        mAppInfo.size() * sizeof(mAppInfo[0]));
        complete();
    }

    return 0;
}

int SystemComm::AppInfoSession::requestNext()
{
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    buf.writeU8(NANOHUB_QUERY_APPS);
    buf.writeU32(mAppInfo.size());
    return sendToSystem(buf.getData(), buf.getPos());
}

int SystemComm::GlobalSession::setup(const hub_message_t *) {
    Mutex::Autolock _l(mLock);

    setState(SESSION_USER);

    return 0;
}

int SystemComm::GlobalSession::handleRx(MessageBuf &buf)
{
    Mutex::Autolock _l(mLock);

    NanohubRsp rsp(buf);
    if (rsp.cmd != NANOHUB_REBOOT) {
        return 1;
    }

    ALOGW("Nanohub reboot status [UNSOLICITED]: %08" PRIX32, rsp.status);
    sendToApp(CONTEXT_HUB_OS_REBOOT, &rsp.status, sizeof(rsp.status));

    return 0;
}

int SystemComm::MemInfoSession::setup(const hub_message_t *)
{
    Mutex::Autolock _l(mLock);
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    buf.writeU8(NANOHUB_QUERY_MEMINFO);

    setState(SESSION_USER);
    return sendToSystem(buf.getData(), buf.getPos());
}

int SystemComm::MemInfoSession::handleRx(MessageBuf &buf)
{
    Mutex::Autolock _l(mLock);
    NanohubRsp rsp(buf, true);

    if (rsp.cmd != NANOHUB_QUERY_MEMINFO)
        return 1;

    size_t len = buf.getRoom();

    if (len != sizeof(NanohubMemInfo)) {
        ALOGE("%s: Invalid data size: %zu", __func__, len);
        return -EINVAL;
    }
    if (getState() != SESSION_USER) {
        ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
        return -EINVAL;
    }

    NanohubMemInfo mi;
    readNanohubMemInfo(buf, mi);
    std::vector<mem_range_t> ranges;
    ranges.reserve(4);

    //if each is valid, copy to output area
    if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN &&
        mi.sharedUse != NANOHUB_MEM_SZ_UNKNOWN)
        ranges.push_back({
            .type = HUB_MEM_TYPE_MAIN,
            .total_bytes = mi.sharedSz,
            .free_bytes = mi.sharedSz - mi.sharedUse,
        });

    if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN &&
        mi.osUse != NANOHUB_MEM_SZ_UNKNOWN)
        ranges.push_back({
            .type = HUB_MEM_TYPE_OS,
            .total_bytes = mi.osSz,
            .free_bytes = mi.osSz - mi.osUse,
        });

    if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN &&
        mi.eeUse != NANOHUB_MEM_SZ_UNKNOWN)
        ranges.push_back({
            .type = HUB_MEM_TYPE_EEDATA,
            .total_bytes = mi.eeSz,
            .free_bytes = mi.eeSz - mi.eeUse,
        });

    if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN &&
        mi.ramUse != NANOHUB_MEM_SZ_UNKNOWN)
        ranges.push_back({
            .type = HUB_MEM_TYPE_RAM,
            .total_bytes = mi.ramSz,
            .free_bytes = mi.ramSz - mi.ramUse,
        });

    //send it out
    sendToApp(CONTEXT_HUB_QUERY_MEMORY,
              static_cast<const void *>(ranges.data()),
              ranges.size() * sizeof(ranges[0]));

    complete();

    return 0;
}

int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
{
    Mutex::Autolock _l(mLock);

    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    const uint8_t *msgData = static_cast<const uint8_t*>(appMsg->message);

    mCmd = appMsg->message_type;
    mLen = appMsg->message_len;
    mPos = 0;

    switch (mCmd) {
    case  CONTEXT_HUB_APPS_ENABLE:
        return setupMgmt(appMsg, NANOHUB_EXT_APPS_ON);
    case  CONTEXT_HUB_APPS_DISABLE:
        return setupMgmt(appMsg, NANOHUB_EXT_APPS_OFF);
    case  CONTEXT_HUB_UNLOAD_APP:
        return setupMgmt(appMsg, NANOHUB_EXT_APP_DELETE);
    case  CONTEXT_HUB_LOAD_OS:
    case  CONTEXT_HUB_LOAD_APP:
        mData.clear();
        mData = std::vector<uint8_t>(msgData, msgData + mLen);
        setState(TRANSFER);

        buf.writeU8(NANOHUB_START_UPLOAD);
        buf.writeU8(mCmd == CONTEXT_HUB_LOAD_OS ? 1 : 0);
        buf.writeU32(mLen);
        return sendToSystem(buf.getData(), buf.getPos());

    case  CONTEXT_HUB_OS_REBOOT:
        setState(REBOOT);
        buf.writeU8(NANOHUB_REBOOT);
        return sendToSystem(buf.getData(), buf.getPos());
    }

    return -EINVAL;
}

int SystemComm::AppMgmtSession::setupMgmt(const hub_message_t *appMsg, uint32_t cmd)
{
    const hub_app_name_t &appName = *static_cast<const hub_app_name_t*>(appMsg->message);
    if (appMsg->message_len != sizeof(appName)) {
        return -EINVAL;
    }

    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    buf.writeU8(cmd);
    writeAppName(buf, appName);
    setState(MGMT);

    return sendToSystem(buf.getData(), buf.getPos());
}

int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf)
{
    int ret = 0;
    Mutex::Autolock _l(mLock);
    NanohubRsp rsp(buf);

    switch (getState()) {
    case TRANSFER:
        ret = handleTransfer(rsp);
        break;
    case FINISH:
        ret = handleFinish(rsp);
        break;
    case RELOAD:
        ret = handleReload(rsp);
        break;
    case REBOOT:
        ret = handleReboot(rsp);
        break;
    case MGMT:
        ret = handleMgmt(rsp);
        break;
    }

    return ret;
}

int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp)
{
    if (rsp.cmd != NANOHUB_CONT_UPLOAD && rsp.cmd != NANOHUB_START_UPLOAD)
        return 1;

    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));

    static_assert(NANOHUB_UPLOAD_CHUNK_SZ_MAX <= (MAX_RX_PACKET-5),
                  "Invalid chunk size");

    if (mPos < mLen) {
        uint32_t chunkSize = mLen - mPos;

        if (chunkSize > NANOHUB_UPLOAD_CHUNK_SZ_MAX) {
            chunkSize = NANOHUB_UPLOAD_CHUNK_SZ_MAX;
        }

        buf.writeU8(NANOHUB_CONT_UPLOAD);
        buf.writeU32(mPos);
        buf.writeRaw(&mData[mPos], chunkSize);
        mPos += chunkSize;
    } else {
        buf.writeU8(NANOHUB_FINISH_UPLOAD);
        setState(FINISH);
    }

    return sendToSystem(buf.getData(), buf.getPos());
}

int SystemComm::AppMgmtSession::handleFinish(NanohubRsp &rsp)
{
    if (rsp.cmd != NANOHUB_FINISH_UPLOAD)
        return 1;

    int ret = 0;
    const bool success = rsp.status != 0;
    mData.clear();

    if (success) {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        // until app header is passed, we don't know who to start, so we reboot
        buf.writeU8(NANOHUB_REBOOT);
        setState(RELOAD);
        ret = sendToSystem(buf.getData(), buf.getPos());
    } else {
        int32_t result = NANOHUB_APP_NOT_LOADED;

        sendToApp(mCmd, &result, sizeof(result));
        complete();
    }

    return ret;
}

/* reboot notification, when triggered as part of App reload sequence */
int SystemComm::AppMgmtSession::handleReload(NanohubRsp &rsp)
{
    int32_t result = NANOHUB_APP_LOADED;

    ALOGI("Nanohub reboot status [NEW APP START]: %08" PRIX32, rsp.status);

    sendToApp(mCmd, &result, sizeof(result));

    // in addition to sending response to the CONTEXT_HUB_LOAD_APP command,
    // we should send unsolicited reboot notification;
    // I choose to do it here rather than delegate it to global session
    // because I want the log to clearly differentiate between UNSOLICITED reboots
    // (meaning FW faults) and REQUESTED reboots.
    sendToApp(CONTEXT_HUB_OS_REBOOT, &rsp.status, sizeof(rsp.status));

    complete();

    return 0;
}

/* reboot notification, when triggered by App request */
int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp)
{
    ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32, rsp.status);

    sendToApp(mCmd, &rsp.status, sizeof(rsp.status));
    complete();

    return 0;
}

int SystemComm::AppMgmtSession::handleMgmt(NanohubRsp &rsp)
{
    bool valid = false;

    ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.cmd, rsp.status);

    switch (rsp.cmd) {
    case NANOHUB_EXT_APPS_OFF:
        valid = mCmd == CONTEXT_HUB_APPS_DISABLE;
        break;
    case NANOHUB_EXT_APPS_ON:
        valid = mCmd == CONTEXT_HUB_APPS_ENABLE;
        break;
    case NANOHUB_EXT_APP_DELETE:
        valid = mCmd == CONTEXT_HUB_UNLOAD_APP;
        break;
    default:
        return 1;
    }

    if (!valid) {
        ALOGE("Invalid response for this state: APP CMD=%02X", mCmd);
        return -EINVAL;
    }

    sendToApp(mCmd, &rsp.status, sizeof(rsp.status));
    complete();

    return 0;
}

int SystemComm::KeyInfoSession::setup(const hub_message_t *) {
    Mutex::Autolock _l(mLock);
    mRsaKeyData.clear();
    setState(SESSION_USER);
    mStatus = -EBUSY;
    return requestRsaKeys();
}

int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
{
    Mutex::Autolock _l(mLock);
    NanohubRsp rsp(buf, true);

    if (getState() != SESSION_USER) {
        // invalid state
        mStatus = -EFAULT;
        return mStatus;
    }

    if (buf.getRoom()) {
        mRsaKeyData.insert(mRsaKeyData.end(),
                           buf.getData() + buf.getPos(),
                           buf.getData() + buf.getSize());
        return requestRsaKeys();
    } else {
        mStatus = 0;
        complete();
        return 0;
    }
}

int SystemComm::KeyInfoSession::requestRsaKeys(void)
{
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));

    buf.writeU8(NANOHUB_QUERY_APPS);
    buf.writeU32(mRsaKeyData.size());

    return sendToSystem(buf.getData(), buf.getPos());
}

int SystemComm::doHandleRx(const nano_message *msg)
{
    //we only care for messages from HostIF
    if (msg->hdr.app_name != mHostIfAppName)
        return 1;

    //they must all be at least 1 byte long
    if (!msg->hdr.len) {
        return -EINVAL;
    }
    MessageBuf buf(reinterpret_cast<const char*>(msg->data), msg->hdr.len);
    if (NanoHub::messageTracingEnabled()) {
        dumpBuffer("SYS -> HAL", mHostIfAppName, 0, buf.getData(), buf.getSize());
    }
    int status = mSessions.handleRx(buf);
    if (status) {
        // provide default handler for any system message, that is not properly handled
        dumpBuffer(status > 0 ? "HAL (not handled)" : "HAL (error)",
                   mHostIfAppName, 0, buf.getData(), buf.getSize(), status);
        status = status > 0 ? 0 : status;
    }

    return status;
}

int SystemComm::SessionManager::handleRx(MessageBuf &buf)
{
    int status = 1;

    // pass message to all active sessions, in arbitrary order
    // 1st session that handles the message terminates the loop
    for (auto pos = sessions_.begin();
         pos != sessions_.end() && status > 0; next(pos)) {
        Session *session = pos->second;
        status = session->handleRx(buf);
        if (status < 0) {
            session->complete();
        }
    }
    if (status > 0) {
        status = mGlobal.handleRx(buf);
    }

    return status;
}

int SystemComm::doHandleTx(const hub_message_t *appMsg)
{
    int status = 0;

    switch (appMsg->message_type) {
    case CONTEXT_HUB_LOAD_APP:
        if (!mKeySession.haveKeys()) {
            status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mKeySession, appMsg);
            if (status < 0) {
                break;
            }
            mKeySession.wait();
            status = mKeySession.getStatus();
            if (status < 0) {
                break;
            }
        }
        status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
        break;
    case CONTEXT_HUB_APPS_ENABLE:
    case CONTEXT_HUB_APPS_DISABLE:
    case CONTEXT_HUB_UNLOAD_APP:
        // all APP-modifying commands share session key, to ensure they can't happen at the same time
        status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
        break;

    case CONTEXT_HUB_QUERY_APPS:
        status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_APPS, &mAppInfoSession, appMsg);
        break;

    case CONTEXT_HUB_QUERY_MEMORY:
        status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_MEMORY, &mMemInfoSession, appMsg);
        break;

    default:
        ALOGW("Unknown os message type %u\n", appMsg->message_type);
        return -EINVAL;
    }

   return status;
}

}; // namespace nanohub

}; // namespace android
