/*
 * 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 <fcntl.h>
#include <poll.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <hardware/context_hub.h>
#include <hardware/hardware.h>

#include <utils/Log.h>
#include <cutils/properties.h>

#include <nanohub/nanohub.h>

#include <cinttypes>
#include <iomanip>
#include <sstream>

#include "nanohub_perdevice.h"
#include "system_comms.h"
#include "nanohubhal.h"

#define NANOHUB_LOCK_DIR        "/data/system/nanohub_lock"
#define NANOHUB_LOCK_FILE       NANOHUB_LOCK_DIR "/lock"
#define NANOHUB_LOCK_DIR_PERMS  (S_IRUSR | S_IWUSR | S_IXUSR)

namespace android {

namespace nanohub {

inline std::ostream &operator << (std::ostream &os, const hub_app_name_t &appId)
{
    char vendor[6];
    __be64 beAppId = htobe64(appId.id);
    uint32_t seqId = appId.id & NANOAPP_VENDOR_ALL_APPS;

    std::ios::fmtflags f(os.flags());
    memcpy(vendor, (void*)&beAppId, sizeof(vendor) - 1);
    vendor[sizeof(vendor) - 1] = 0;
    if (strlen(vendor) == 5)
        os << vendor << ", " << std::hex << std::setw(6)  << seqId;
    else
        os << "#" << std::hex << appId.id;
    os.flags(f);

    return os;
}

void dumpBuffer(const char *pfx, const hub_app_name_t &appId, uint32_t evtId, const void *data, size_t len, int status)
{
    std::ostringstream os;
    const uint8_t *p = static_cast<const uint8_t *>(data);
    os << pfx << ": [ID=" << appId << "; SZ=" << std::dec << len;
    if (evtId)
        os << "; EVT=" << std::hex << evtId;
    os << "]:" << std::hex;
    for (size_t i = 0; i < len; ++i) {
        os << " "  << std::setfill('0') << std::setw(2) << (unsigned int)p[i];
    }
    if (status) {
        os << "; status=" << status << " [" << std::setfill('0') << std::setw(8) << status << "]";
    }
    ALOGI("%s", os.str().c_str());
}

static int rwrite(int fd, const void *buf, int len)
{
    int ret;

    do {
        ret = write(fd, buf, len);
    } while (ret < 0 && errno == EINTR);

    if (ret != len) {
        return errno ? -errno : -EIO;
    }

    return 0;
}

static int rread(int fd, void *buf, int len)
{
    int ret;

    do {
        ret = read(fd, buf, len);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

static bool init_inotify(pollfd *pfd) {
    bool success = false;

    mkdir(NANOHUB_LOCK_DIR, NANOHUB_LOCK_DIR_PERMS);
    pfd->fd = inotify_init1(IN_NONBLOCK);
    if (pfd->fd < 0) {
        ALOGE("Couldn't initialize inotify: %s", strerror(errno));
    } else if (inotify_add_watch(pfd->fd, NANOHUB_LOCK_DIR, IN_CREATE | IN_DELETE) < 0) {
        ALOGE("Couldn't add inotify watch: %s", strerror(errno));
        close(pfd->fd);
    } else {
        pfd->events = POLLIN;
        success = true;
    }

    return success;
}

static void discard_inotify_evt(pollfd &pfd) {
    if ((pfd.revents & POLLIN)) {
        char buf[sizeof(inotify_event) + NAME_MAX + 1];
        int ret = read(pfd.fd, buf, sizeof(buf));
        ALOGD("Discarded %d bytes of inotify data", ret);
    }
}

static void wait_on_dev_lock(pollfd &pfd) {
    // While the lock file exists, poll on the inotify fd (with timeout)
    discard_inotify_evt(pfd);
    while (access(NANOHUB_LOCK_FILE, F_OK) == 0) {
        ALOGW("Nanohub is locked; blocking read thread");
        int ret = poll(&pfd, 1, 5000);
        if (ret > 0) {
            discard_inotify_evt(pfd);
        }
    }
}

NanoHub::NanoHub() {
    reset();
}

NanoHub::~NanoHub() {
    if (mMsgCbkFunc) {
        ALOGD("Shutting down");
        closeHub();
    }
}

int NanoHub::doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len, uint32_t messageType)
{
    if (len > MAX_RX_PACKET) {
        return -EINVAL;
    }

    // transmit message to FW in CHRE format
    nano_message_chre msg = {
        .hdr = {
            .eventId = APP_FROM_HOST_CHRE_EVENT_ID,
            .appId = name.id,
            .len = static_cast<uint8_t>(len),
            .appEventId = messageType,
        },
    };

    memcpy(&msg.data[0], data, len);

    return rwrite(mFd, &msg, len + sizeof(msg.hdr));
}

void NanoHub::doSendToApp(HubMessage &&msg)
{
    std::unique_lock<std::mutex> lk(mAppTxLock);
    mAppTxQueue.push_back((HubMessage &&)msg);
    lk.unlock();
    mAppTxCond.notify_all();
}

void* NanoHub::runAppTx()
{
    std::unique_lock<std::mutex> lk(mAppTxLock);
    while(true) {
        mAppTxCond.wait(lk, [this] { return !mAppTxQueue.empty() || mAppQuit; });
        if (mAppQuit) {
            break;
        }
        HubMessage &m = mAppTxQueue.front();
        lk.unlock();
        mMsgCbkFunc(0, &m, mMsgCbkData);
        lk.lock();
        mAppTxQueue.pop_front();
    };
    return NULL;
}

void* NanoHub::runDeviceRx()
{
    enum {
        IDX_NANOHUB,
        IDX_CLOSE_PIPE,
        IDX_INOTIFY
    };
    pollfd myFds[3] = {
        [IDX_NANOHUB] = { .fd = mFd, .events = POLLIN, },
        [IDX_CLOSE_PIPE] = { .fd = mThreadClosingPipe[0], .events = POLLIN, },
    };
    pollfd &inotifyFd = myFds[IDX_INOTIFY];
    bool hasInotify = false;
    int numPollFds = 2;

    if (init_inotify(&inotifyFd)) {
        numPollFds++;
        hasInotify = true;
    }

    setDebugFlags(property_get_int32("persist.nanohub.debug", 0));

    while (1) {
        int ret = poll(myFds, numPollFds, -1);
        if (ret <= 0) {
            ALOGD("poll returned with an error: %s", strerror(errno));
            continue;
        }

        if (hasInotify) {
            wait_on_dev_lock(inotifyFd);
        }

        if (myFds[IDX_NANOHUB].revents & POLLIN) { // we have data

            nano_message msg;

            ret = rread(mFd, &msg, sizeof(msg));
            if (ret <= 0) {
                ALOGE("read failed with %d", ret);
                break;
            }
            if (ret < (int)sizeof(msg.hdr)) {
                ALOGE("Only read %d bytes", ret);
                break;
            }

            uint32_t len = msg.hdr.len;

            if (len > sizeof(msg.data)) {
                ALOGE("malformed packet with len %" PRIu32, len);
                break;
            }

            // receive message from FW in legacy format
            if (ret != (int)(sizeof(msg.hdr) + len)) {
                ALOGE("Expected %zu bytes, read %d bytes", sizeof(msg.hdr) + len, ret);
                break;
            }

            ret = SystemComm::handleRx(&msg);
            if (ret < 0) {
                ALOGE("SystemComm::handleRx() returned %d", ret);
            } else if (ret) {
                hub_app_name_t app_name = { .id = msg.hdr.appId };
                if (messageTracingEnabled()) {
                    dumpBuffer("DEV -> APP", app_name, msg.hdr.eventId, &msg.data[0], msg.hdr.len);
                }
                doSendToApp(HubMessage(&app_name, msg.hdr.eventId, &msg.data[0], msg.hdr.len));
            }
        }

        if (myFds[IDX_CLOSE_PIPE].revents & POLLIN) { // we have been asked to die
            ALOGD("thread exiting");
            break;
        }
    }

    close(mFd);
    return NULL;
}

int NanoHub::openHub()
{
    int ret = 0;

    mFd = open(get_devnode_path(), O_RDWR);
    if (mFd < 0) {
        ALOGE("cannot find hub devnode '%s'", get_devnode_path());
        ret = -errno;
        goto fail_open;
    }

    if (pipe(mThreadClosingPipe)) {
        ALOGE("failed to create signal pipe");
        ret = -errno;
        goto fail_pipe;
    }

    mPollThread = std::thread([this] { runDeviceRx(); });
    mAppThread = std::thread([this] { runAppTx(); });
    return 0;

fail_pipe:
    close(mFd);

fail_open:
    return ret;
}

int NanoHub::closeHub(void)
{
    char zero = 0;

    // stop mPollThread
    while(write(mThreadClosingPipe[1], &zero, 1) != 1) {
        continue;
    }

    // stop mAppThread
    {
        std::unique_lock<std::mutex> lk(mAppTxLock);
        mAppQuit = true;
        lk.unlock();
        mAppTxCond.notify_all();
    }

    //wait
    if (mPollThread.joinable()) {
        mPollThread.join();
    }

    //wait
    if (mAppThread.joinable()) {
        mAppThread.join();
    }
    //cleanup
    ::close(mThreadClosingPipe[0]);
    ::close(mThreadClosingPipe[1]);
    ::close(mFd);

    reset();

    return 0;
}

int NanoHub::doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie)
{
    if (hub_id) {
        return -ENODEV;
    }

    std::lock_guard<std::mutex> _l(mLock);
    int ret = 0;

    if (!mMsgCbkFunc && !cbk) { //we're off and staying off - do nothing

        ALOGD("staying off");
    } else if (cbk && mMsgCbkFunc) { //new callback but staying on

        ALOGD("staying on");
    } else if (mMsgCbkFunc) {     //we were on but turning off

        ALOGD("turning off");

        ret = closeHub();
    } else if (cbk) {             //we're turning on

        ALOGD("turning on");
        ret = openHub();
    }

    mMsgCbkFunc = cbk;
    mMsgCbkData = cookie;

    return ret;
}

int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg)
{
    if (hub_id) {
        return -ENODEV;
    }

    int ret = 0;
    std::lock_guard<std::mutex> _l(mLock);

    if (!mMsgCbkFunc) {
        ALOGW("refusing to send a message when nobody around to get a reply!");
        ret = -EIO;
    } else {
        if (!msg || !msg->message) {
            ALOGW("not sending invalid message 1");
            ret = -EINVAL;
        } else if (get_hub_info()->os_app_name == msg->app_name) {
            //messages to the "system" app are special - hal handles them
            if (messageTracingEnabled()) {
                dumpBuffer("APP -> HAL", msg->app_name, msg->message_type, msg->message, msg->message_len);
            }
            ret = SystemComm::handleTx(msg);
        } else if (msg->message_len > MAX_RX_PACKET) {
            ALOGW("not sending invalid message 2");
            ret = -EINVAL;
        } else {
            if (messageTracingEnabled()) {
                dumpBuffer("APP -> DEV", msg->app_name, msg->message_type, msg->message, msg->message_len);
            }
            ret = doSendToDevice(msg->app_name, msg->message, msg->message_len, msg->message_type);
        }
    }

    return ret;
}

static int hal_get_hubs(context_hub_module_t*, const context_hub_t ** list)
{
    *list = get_hub_info();

    return 1; /* we have one hub */
}

}; // namespace nanohub

}; // namespace android

context_hub_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = CONTEXT_HUB_DEVICE_API_VERSION_1_0,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = CONTEXT_HUB_MODULE_ID,
        .name = "Nanohub HAL",
        .author = "Google",
    },

    .get_hubs = android::nanohub::hal_get_hubs,
    .subscribe_messages = android::nanohub::NanoHub::subscribeMessages,
    .send_message = android::nanohub::NanoHub::sendToNanohub,
};
