/*
 * Copyright 2016 The Fuchsia Authors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "FuchsiaInputHandler.h"

#include <wtf/Assertions.h>

#include <dirent.h>
#include <fcntl.h>
#include <hid/hid.h>
#include <hid/usages.h>
#include <zircon/device/device.h>
#include <zircon/device/input.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <lib/fdio/io.h>
#include <stdlib.h>

#include <iostream>
#include <sstream>
#include <thread>

const char* kDevInput = "/dev/class/input";

namespace Fuchsia {

using namespace std;

#pragma mark - InputReportHandler

InputReportHandler::InputReportHandler(int descriptor, const std::string& deviceName)
    : fDescriptor(descriptor)
    , fName(deviceName)
{
}

InputReportHandler::~InputReportHandler()
{
}

ssize_t InputReportHandler::openHandle()
{
    zx_handle_t handle;
    ssize_t ret = fdio_ioctl(fDescriptor, IOCTL_DEVICE_GET_EVENT_HANDLE, nullptr, 0,
        &handle, sizeof(handle));
    if (ret >= 0) {
        fHandle = handle;
    }
    return ret;
}

void InputReportHandler::checkForEvents(EventList& events)
{
    size_t max_report_len = 0;
    int rc = fdio_ioctl(fDescriptor, IOCTL_INPUT_GET_MAX_REPORTSIZE, NULL, 0, &max_report_len, sizeof(max_report_len));
    if (rc < 0) {
        WTFLogAlways("hid: could not get max report size from %d: %d", fDescriptor, rc);
    }

    vector<char> buffer(max_report_len);

    int r = read(fDescriptor, &buffer[0], max_report_len);
    handleReport(r, &buffer[0], events);
}

#pragma mark - MouseReportHandler

MouseReportHandler::MouseReportHandler(int descriptor, const std::string& deviceName)
    : InputReportHandler(descriptor, deviceName)
{
}

void MouseReportHandler::handleReport(size_t byteLength, const char* reportData, EventList& events)
{
    const boot_mouse_report_t* mouseReport = reinterpret_cast<const boot_mouse_report_t*>(reportData);
    while (byteLength > 0) {
        EventPtr eventP(new MouseEvent(fDescriptor, mouseReport->rel_x, mouseReport->rel_y, mouseReport->buttons));
        events.push_back(eventP);
        byteLength -= 3;
        mouseReport += 1;
    }
}

#pragma mark - KeyboardReportHandler

KeyboardReportHandler::KeyboardReportHandler(int descriptor, const std::string& deviceName)
    : InputReportHandler(descriptor, deviceName)
{
}

void KeyboardReportHandler::handleReport(size_t byteLength, const char* reportData, EventList& events)
{
    const uint8_t* keyboardReport = reinterpret_cast<const uint8_t*>(reportData);
    uint8_t* keyboardReportWriteableSigh = const_cast<uint8_t*>(keyboardReport);
    uint8_t keycode;
    hid_keys_t newKeyState;
    hid_keys_t keyDelta;
    hid_kbd_parse_report(keyboardReportWriteableSigh, &newKeyState);
    hid_kbd_pressed_keys(&fKeyState, &newKeyState, &keyDelta);
    hid_for_every_key(&keyDelta, keycode) {
        EventPtr eventP(new KeyEvent(fDescriptor, keycode, true));
        events.push_back(eventP);
    }
    hid_kbd_released_keys(&fKeyState, &newKeyState, &keyDelta);
    hid_for_every_key(&keyDelta, keycode) {
        EventPtr eventP(new KeyEvent(fDescriptor, keycode, false));
        events.push_back(eventP);
    }
    fKeyState = newKeyState;
}

#pragma mark - InputHandler

InputHandler::InputHandler()
{
}

static int get_hid_protocol(int fd, const char* name)
{
    int proto = 0;
    int rc = fdio_ioctl(fd, IOCTL_INPUT_GET_PROTOCOL, NULL, 0, &proto, sizeof(proto));
    if (rc < 0) {
        WTFLogAlways("hid: could not get protocol from %s (status=%d)\n", name, rc);
    } else {
        WTFLogAlways("hid: %s proto=%d\n", name, proto);
    }
    return proto;
}

static void checkForEvents(int fd, EventList& events)
{
    size_t max_report_len = 0;
    int rc = fdio_ioctl(fd, IOCTL_INPUT_GET_MAX_REPORTSIZE, NULL, 0, &max_report_len, sizeof(max_report_len));
    if (rc < 0) {
        WTFLogAlways("hid: could not get max report size from %d: %d", fd, rc);
        return;
    }

    vector<char> buffer(max_report_len);

    int proto = 0;
    rc = fdio_ioctl(fd, IOCTL_INPUT_GET_PROTOCOL, NULL, 0, &proto, sizeof(proto));
    if (rc < 0) {
        WTFLogAlways("hid: could not get protocol (status=%d)", rc);
        return;
    }

    int r = read(fd, &buffer[0], max_report_len);

    if (proto == INPUT_PROTO_MOUSE) {
        boot_mouse_report_t* mouseReport = reinterpret_cast<boot_mouse_report_t*>(&buffer[0]);
        while (r > 0) {
            EventPtr eventP(new MouseEvent(fd, mouseReport->rel_x, mouseReport->rel_y, mouseReport->buttons));
            events.push_back(eventP);
            r -= 3;
            mouseReport += 1;
        }
    } else if (proto == INPUT_PROTO_KBD) {
        boot_kbd_report* kbdReport = reinterpret_cast<boot_kbd_report*>(&buffer[0]);
        while (r > 0) {
            WTFLogAlways("keyboard action");
            r -= sizeof(boot_kbd_report);
            kbdReport += 1;
        }
    }
}

static EventList waitForEvents(vector<InputReportHandlerPtr> reportHandlers)
{
    EventList events;
    vector<zx_wait_item_t> items;
    for (const auto& oneReportHandler : reportHandlers) {
        zx_wait_item_t item = { oneReportHandler->handle(), DEVICE_SIGNAL_READABLE, 0 };
        items.push_back(item);
    }
    zx_status_t result = zx_object_wait_many(&items[0], items.size(),
        ZX_TIME_INFINITE);
    if (result == ZX_OK) {
        int index = 0;
        for (const auto& oneItem : items) {
            if (oneItem.pending & DEVICE_SIGNAL_READABLE) {
                auto& oneReportHandler(reportHandlers[index]);
                oneReportHandler->checkForEvents(events);
            }
            index += 1;
        }
    }
    return events;
}

void InputHandler::openDevices()
{
    struct dirent* de;
    DIR* dir = opendir(kDevInput);
    if (!dir) {
        WTFLogAlways("hid: error opening %s", kDevInput);
        return;
    }

    while ((de = readdir(dir)) != NULL) {
        ostringstream oss;
        oss << kDevInput << "/" << de->d_name;
        string dname(oss.str());
        int fd = open(dname.c_str(), O_RDONLY);
        if (fd >= 0) {
            int proto = get_hid_protocol(fd, dname.c_str());
            InputReportHandlerPtr p;
            if (proto == INPUT_PROTO_MOUSE) {
                p.reset(new MouseReportHandler(fd, dname));
            } else if (proto == INPUT_PROTO_KBD) {
                p.reset(new KeyboardReportHandler(fd, dname));
            } else {
                close(fd);
            }

            if (p) {
                if (p->openHandle() >= 0) {
                    fReportHandlers.push_back(p);
                }
            }
        }
    }

    startReaderThread();
}

bool InputHandler::hasEvents()
{
    std::lock_guard<std::mutex> lock(fEventsMutex);
    bool v = !fEvents.empty();
    return v;
}

EventList InputHandler::getPendingEvents()
{
    std::lock_guard<std::mutex> lock(fEventsMutex);
    EventList pending(fEvents);
    fEvents.clear();
    return pending;
}

void InputHandler::addEvents(const EventList& newEvents)
{
    std::lock_guard<std::mutex> lock(fEventsMutex);
    fEvents.insert(std::end(fEvents), std::begin(newEvents), std::end(newEvents));
}

void InputHandler::readEvents()
{
    while(1) {
        EventList newEvents = waitForEvents(fReportHandlers);
        addEvents(newEvents);
    }
}

void InputHandler::startReaderThread()
{
    fEventReaderThread = std::thread(&InputHandler::readEvents,this);
}

}
