// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <limits.h>

#include <fbl/algorithm.h>
#include <fbl/unique_ptr.h>
#include <fuchsia/hardware/input/c/fidl.h>
#include <lib/fdio/watcher.h>
#include <lib/fzl/fdio.h>
#include <zircon/assert.h>
#include <zircon/listnode.h>
#include <zircon/threads.h>
#include <zircon/types.h>

#include <utility>

// defined in report.cpp
void print_report_descriptor(const uint8_t* rpt_desc, size_t desc_len);

#define DEV_INPUT "/dev/class/input"

static bool verbose = false;
#define xprintf(fmt...) do { if (verbose) printf(fmt); } while (0)

void usage(void) {
    printf("usage: hid [-v] <command> [<args>]\n\n");
    printf("  commands:\n");
    printf("    read [<devpath> [num reads]]\n");
    printf("    get <devpath> <in|out|feature> <id>\n");
    printf("    set <devpath> <in|out|feature> <id> [0xXX *]\n");
    printf("    parse <devpath>\n");
}

typedef struct input_args {
    fbl::unique_fd fd;
    char name[128];
    unsigned long int num_reads;
} input_args_t;

static thrd_t input_poll_thread;

static mtx_t print_lock = MTX_INIT;
#define lprintf(fmt...) \
    do { \
        mtx_lock(&print_lock); \
        printf(fmt); \
        mtx_unlock(&print_lock); \
    } while (0)


static void print_hex(uint8_t* buf, size_t len) {
    for (size_t i = 0; i < len; i++) {
        printf("%02x ", buf[i]);
        if (i % 16 == 15) printf("\n");
    }
    printf("\n");
}

static zx_status_t parse_uint_arg(const char* arg, uint32_t min, uint32_t max, uint32_t* out_val) {
    if ((arg == NULL) || (out_val == NULL)) {
        return ZX_ERR_INVALID_ARGS;
    }

    bool is_hex = (arg[0] == '0') && (arg[1] == 'x');
    if (sscanf(arg, is_hex ? "%x" : "%u", out_val) != 1) {
        return ZX_ERR_INVALID_ARGS;
    }

    if ((*out_val < min) || (*out_val > max)) {
        return ZX_ERR_OUT_OF_RANGE;
    }

    return ZX_OK;
}

static zx_status_t parse_input_report_type(const char* arg,
                                           fuchsia_hardware_input_ReportType* out_type) {
    if ((arg == NULL) || (out_type == NULL)) {
        return ZX_ERR_INVALID_ARGS;
    }

    static const struct {
        const char* name;
        fuchsia_hardware_input_ReportType type;
    } LUT[] = {
        {.name = "in", .type = fuchsia_hardware_input_ReportType_INPUT},
        {.name = "out", .type = fuchsia_hardware_input_ReportType_OUTPUT},
        {.name = "feature", .type = fuchsia_hardware_input_ReportType_FEATURE},
    };

    for (size_t i = 0; i < fbl::count_of(LUT); ++i) {
        if (!strcasecmp(arg, LUT[i].name)) {
            *out_type = LUT[i].type;
            return ZX_OK;
        }
    }

    return ZX_ERR_INVALID_ARGS;
}

static zx_status_t parse_set_get_report_args(int argc, const char** argv, uint8_t* out_id,
                                             fuchsia_hardware_input_ReportType* out_type) {
    if ((argc < 3) || (argv == NULL) || (out_id == NULL) || (out_type == NULL)) {
        return ZX_ERR_INVALID_ARGS;
    }

    zx_status_t res;
    uint32_t tmp;
    res = parse_uint_arg(argv[2], 0, 255, &tmp);
    if (res != ZX_OK) {
        return res;
    }

    *out_id = static_cast<uint8_t>(tmp);

    return parse_input_report_type(argv[1], out_type);
}

static zx_status_t get_hid_protocol(const fzl::FdioCaller& caller, const char* name) {
    uint32_t proto;
    zx_status_t status =
        fuchsia_hardware_input_DeviceGetBootProtocol(caller.borrow_channel(), &proto);
    if (status != ZX_OK) {
        lprintf("hid: could not get protocol from %s (status=%d)\n", name, status);
    } else {
        lprintf("hid: %s proto=%d\n", name, proto);
    }
    return status;
}

static zx_status_t get_report_desc_len(const fzl::FdioCaller& caller, const char* name,
                                       size_t* report_desc_len) {
    uint16_t len;
    zx_status_t status =
        fuchsia_hardware_input_DeviceGetReportDescSize(caller.borrow_channel(), &len);
    if (status != ZX_OK) {
        lprintf("hid: could not get report descriptor length from %s (status=%d)\n", name, status);
    } else {
        *report_desc_len = len;
        lprintf("hid: %s report descriptor len=%zu\n", name, *report_desc_len);
    }
    return status;
}

static zx_status_t get_report_desc(const fzl::FdioCaller& caller, const char* name,
                                   size_t report_desc_len) {
    fbl::unique_ptr<uint8_t[]> buf(new uint8_t[report_desc_len]);

    size_t actual;
    zx_status_t status = fuchsia_hardware_input_DeviceGetReportDesc(
        caller.borrow_channel(), buf.get(), report_desc_len, &actual);
    if (status != ZX_OK) {
        lprintf("hid: could not get report descriptor from %s (status=%d)\n", name, status);
        return status;
    }
    if (actual != report_desc_len) {
        lprintf("hid: got unexpected length on report descriptor: %zu versus %zu\n", actual,
                report_desc_len);
        return ZX_ERR_BAD_STATE;
    }
    mtx_lock(&print_lock);
    printf("hid: %s report descriptor:\n", name);
    if (verbose) {
        print_hex(buf.get(), report_desc_len);
    }
    print_report_descriptor(buf.get(), report_desc_len);
    mtx_unlock(&print_lock);
    return status;
}

static zx_status_t get_num_reports(const fzl::FdioCaller& caller, const char* name,
                                   size_t* num_reports) {
    uint16_t count;
    zx_status_t status =
        fuchsia_hardware_input_DeviceGetNumReports(caller.borrow_channel(), &count);
    if (status != ZX_OK) {
        lprintf("hid: could not get number of reports from %s (status=%d)\n", name, status);
    } else {
        *num_reports = count;
        lprintf("hid: %s num reports: %zu\n", name, *num_reports);
    }
    return status;
}

static zx_status_t get_report_ids(const fzl::FdioCaller& caller, const char* name,
                                  size_t num_reports) {
    fbl::unique_ptr<uint8_t[]> ids(new uint8_t[num_reports]);

    size_t actual;
    zx_status_t status = fuchsia_hardware_input_DeviceGetReportIds(caller.borrow_channel(),
                                                                   ids.get(), num_reports, &actual);
    if (status != ZX_OK) {
        lprintf("hid: could not get report ids from %s (status=%d)\n", name, status);
        return status;
    }
    if (actual != num_reports) {
        lprintf("hid: got unexpected number of reports: %zu versus %zu\n", actual, num_reports);
        return ZX_ERR_BAD_STATE;
    }

    mtx_lock(&print_lock);
    printf("hid: %s report ids...\n", name);
    for (size_t i = 0; i < num_reports; i++) {
        static const struct {
            fuchsia_hardware_input_ReportType type;
            const char* tag;
        } TYPES[] = {
            {.type = fuchsia_hardware_input_ReportType_INPUT, .tag = "Input"},
            {.type = fuchsia_hardware_input_ReportType_OUTPUT, .tag = "Output"},
            {.type = fuchsia_hardware_input_ReportType_FEATURE, .tag = "Feature"},
        };

        bool found = false;
        for (size_t j = 0; j < fbl::count_of(TYPES); ++j) {
            uint16_t size;

            zx_status_t call_status;
            status = fuchsia_hardware_input_DeviceGetReportSize(
                caller.borrow_channel(), TYPES[j].type, ids[i], &call_status, &size);
            if (status == ZX_OK && call_status == ZX_OK) {
                printf("  ID 0x%02x : TYPE %7s : SIZE %u bytes\n", ids[i], TYPES[j].tag, size);
                found = true;
            }
        }

        if (!found) {
            printf("  hid: failed to find any report sizes for report id 0x%02x's (dev %s)\n",
                    ids[i], name);
        }
    }

    mtx_unlock(&print_lock);
    return status;
}

static zx_status_t get_max_report_len(const fzl::FdioCaller& caller, const char* name,
                                      uint16_t* max_report_len) {
    uint16_t tmp;
    if (max_report_len == NULL) {
        max_report_len = &tmp;
    }
    zx_status_t status =
        fuchsia_hardware_input_DeviceGetMaxInputReportSize(caller.borrow_channel(), max_report_len);
    if (status != ZX_OK) {
        lprintf("hid: could not get max report size from %s (status=%d)\n", name, status);
    } else {
        lprintf("hid: %s maxreport=%u\n", name, *max_report_len);
    }
    return status;
}

#define TRY(fn)                  \
    do {                         \
        zx_status_t status = fn; \
        if (status != ZX_OK)     \
            return status;       \
    } while (0)

static zx_status_t hid_status(const fzl::FdioCaller& caller, const char* name,
                              uint16_t* max_report_len) {
    size_t num_reports;

    TRY(get_hid_protocol(caller, name));
    TRY(get_num_reports(caller, name, &num_reports));
    TRY(get_report_ids(caller, name, num_reports));
    TRY(get_max_report_len(caller, name, max_report_len));
    return ZX_OK;
}

static zx_status_t parse_rpt_descriptor(const fzl::FdioCaller& caller, const char* name) {
    size_t report_desc_len;
    TRY(get_report_desc_len(caller, "", &report_desc_len));
    TRY(get_report_desc(caller, "", report_desc_len));
    return ZX_OK;
}

#undef TRY

static int hid_input_thread(void* arg) {
    input_args_t* args = (input_args_t*)arg;
    lprintf("hid: input thread started for %s\n", args->name);

    fzl::FdioCaller caller(std::move(args->fd));

    uint16_t max_report_len = 0;
    ssize_t rc = hid_status(caller, args->name, &max_report_len);
    if (rc < 0) {
        return static_cast<int>(rc);
    }

    // Add 1 to the max report length to make room for a Report ID.
    max_report_len++;
    fbl::unique_ptr<uint8_t[]> report(new uint8_t[max_report_len]);

    args->fd = caller.release();
    for (uint32_t i = 0; i < args->num_reads; i++) {
        ssize_t r = read(args->fd.get(), report.get(), max_report_len);
        mtx_lock(&print_lock);
        printf("read returned %ld\n", r);
        if (r < 0) {
            printf("read errno=%d (%s)\n", errno, strerror(errno));
            mtx_unlock(&print_lock);
            break;
        }
        printf("hid: input from %s\n", args->name);
        print_hex(report.get(), r);
        mtx_unlock(&print_lock);
    }

    lprintf("hid: closing %s\n", args->name);
    delete args;
    return ZX_OK;
}

static zx_status_t hid_input_device_added(int dirfd, int event, const char* fn, void* cookie) {
    if (event != WATCH_EVENT_ADD_FILE) {
        return ZX_OK;
    }

    int fd = openat(dirfd, fn, O_RDONLY);
    if (fd < 0) {
        return ZX_OK;
    }

    input_args_t* args = new input_args {};
    args->fd = fbl::unique_fd(fd);
    // TODO: support setting num_reads across all devices. requires a way to
    // signal shutdown to all input threads.
    args->num_reads = ULONG_MAX;
    thrd_t t;
    snprintf(args->name, sizeof(args->name), "hid-input-%s", fn);
    int ret = thrd_create_with_name(&t, hid_input_thread, (void*)args, args->name);
    if (ret != thrd_success) {
        printf("hid: input thread %s did not start (error=%d)\n", args->name, ret);
        close(fd);
        return thrd_status_to_zx_status(ret);
    }
    thrd_detach(t);
    return ZX_OK;
}

static int hid_input_devices_poll_thread(void* arg) {
    int dirfd = open(DEV_INPUT, O_DIRECTORY|O_RDONLY);
    if (dirfd < 0) {
        printf("hid: error opening %s\n", DEV_INPUT);
        return ZX_ERR_INTERNAL;
    }
    fdio_watch_directory(dirfd, hid_input_device_added, ZX_TIME_INFINITE, NULL);
    close(dirfd);
    return -1;
}

int read_reports(int argc, const char** argv) {
    argc--;
    argv++;
    if (argc < 1) {
        usage();
        return 0;
    }

    uint32_t tmp = 0xffffffff;
    if (argc > 1) {
        zx_status_t res = parse_uint_arg(argv[1], 0, 0xffffffff, &tmp);
        if (res != ZX_OK) {
            printf("Failed to parse <num reads> (res %d)\n", res);
            usage();
            return 0;
        }
    }

    int fd = open(argv[0], O_RDWR);
    if (fd < 0) {
        printf("could not open %s: %d\n", argv[0], errno);
        return -1;
    }

    input_args_t* args = new input_args_t {};
    args->fd = fbl::unique_fd(fd);
    args->num_reads = tmp;

    strlcpy(args->name, argv[0], sizeof(args->name));
    thrd_t t;
    int ret = thrd_create_with_name(&t, hid_input_thread, (void*)args, args->name);
    if (ret != thrd_success) {
        printf("hid: input thread %s did not start (error=%d)\n", args->name, ret);
        delete args;
        return -1;
    }
    thrd_join(t, NULL);
    return 0;
}

int readall_reports(int argc, const char** argv) {
    int ret = thrd_create_with_name(&input_poll_thread,
                                    hid_input_devices_poll_thread,
                                    NULL,
                                    "hid-inputdev-poll");
    if (ret != thrd_success) {
        return -1;
    }

    thrd_join(input_poll_thread, NULL);
    return 0;
}

int get_report(int argc, const char** argv) {
    argc--;
    argv++;
    if (argc < 3) {
        usage();
        return 0;
    }

    uint8_t id;
    fuchsia_hardware_input_ReportType type;
    zx_status_t res = parse_set_get_report_args(argc, argv, &id, &type);
    if (res != ZX_OK) {
        printf("Failed to parse type/id for get report operation (res %d)\n", res);
        usage();
        return 0;
    }

    int fd = open(argv[0], O_RDWR);
    if (fd < 0) {
        printf("could not open %s: %d\n", argv[0], errno);
        return -1;
    }
    fzl::FdioCaller caller{fbl::unique_fd(fd)};

    xprintf("hid: getting report size for id=0x%02x type=%u\n", id, type);

    uint16_t size;
    zx_status_t call_status;
    res = fuchsia_hardware_input_DeviceGetReportSize(caller.borrow_channel(), type, id,
                                                     &call_status, &size);
    if (res != ZX_OK || call_status != ZX_OK) {
        printf("hid: could not get report (id 0x%02x type %u) size from %s (status=%d, %d)\n",
                id, type, argv[0], res, call_status);
        return static_cast<int>(-1);
    }
    xprintf("hid: report size=%u\n", size);

    // TODO(johngro) : Come up with a better policy than this...  While devices
    // are *supposed* to only deliver a report descriptor's computed size, in
    // practice they frequently seem to deliver number of bytes either greater
    // or fewer than the number of bytes originally requested.  For example...
    //
    // ++ Sometimes a device is expected to deliver a Report ID byte along with
    //    the payload contents, but does not do so.
    // ++ Sometimes it is unclear whether or not a device needs to deliver a
    //    Report ID byte at all since there is only one report listed (and,
    //    sometimes the device delivers that ID, and sometimes it chooses not
    //    to).
    // ++ Sometimes no bytes at all are returned for a report (this seems to
    //    be relatively common for input reports)
    // ++ Sometimes the number of bytes returned has basically nothing to do
    //    with the expected size of the report (this seems to be relatively
    //    common for vendor feature reports).
    //
    // Because of this uncertainty, we currently just provide a worst-case 4KB
    // buffer to read into, and report the number of bytes which came back along
    // with the expected size of the raw report.
    size_t bufsz = 4u << 10;
    size_t actual;
    fbl::unique_ptr<uint8_t[]> buf(new uint8_t[bufsz]);
    res = fuchsia_hardware_input_DeviceGetReport(caller.borrow_channel(), type, id, &call_status,
                                                 buf.get(), bufsz, &actual);
    if (res != ZX_OK || call_status != ZX_OK) {
        printf("hid: could not get report: %d, %d\n", res, call_status);
        return -1;
    }

    printf("hid: got %zu bytes (raw report size %u)\n", actual, size);
    print_hex(buf.get(), actual);
    return 0;
}

int set_report(int argc, const char** argv) {
    argc--;
    argv++;
    if (argc < 4) {
        usage();
        return 0;
    }

    uint8_t id;
    fuchsia_hardware_input_ReportType type;
    zx_status_t res = parse_set_get_report_args(argc, argv, &id, &type);
    if (res != ZX_OK) {
        printf("Failed to parse type/id for get report operation (res %d)\n", res);
        usage();
        return 0;
    }

    xprintf("hid: setting report size for id=0x%02x type=%u\n", id, type);

    int fd = open(argv[0], O_RDWR);
    if (fd < 0) {
        printf("could not open %s: %d\n", argv[0], errno);
        return -1;
    }
    fzl::FdioCaller caller{fbl::unique_fd(fd)};

    // If the set/get report args parsed, then we must have at least 3 arguments.
    ZX_DEBUG_ASSERT(argc >= 3);
    uint16_t payload_size = static_cast<uint16_t>(argc - 3);

    uint16_t size;
    zx_status_t call_status;
    res = fuchsia_hardware_input_DeviceGetReportSize(caller.borrow_channel(), type, id,
                                                     &call_status, &size);
    if (res != ZX_OK || call_status != ZX_OK) {
        printf("hid: could not get report (id 0x%02x type %u) size from %s (status=%d, %d)\n",
                id, type, argv[0], res, call_status);
        return -1;
    }

    xprintf("hid: report size=%u, tx payload size=%u\n", size, payload_size);

    fbl::unique_ptr<uint8_t[]> report(new uint8_t[payload_size]);
    for (int i = 0; i < payload_size; i++) {
        uint32_t tmp;
        zx_status_t res = parse_uint_arg(argv[i+3], 0, 255, &tmp);
        if (res != ZX_OK) {
            printf("Failed to parse payload byte \"%s\" (res = %d)\n", argv[i+3], res);
            return res;
        }

        report[i] = static_cast<uint8_t>(tmp);
    }

    res = fuchsia_hardware_input_DeviceSetReport(caller.borrow_channel(), type, id, report.get(),
                                                 payload_size, &call_status);
    if (res != ZX_OK || call_status != ZX_OK) {
        printf("hid: could not set report: %d, %d\n", res, call_status);
        return -1;
    }

    printf("hid: success\n");
    return 0;
}

int parse(int argc, const char** argv) {
    argc--;
    argv++;
    if (argc < 1) {
        usage();
        return 0;
    }

    int fd = open(argv[0], O_RDWR);
    if (fd < 0) {
        printf("could not open %s: %d\n", argv[0], errno);
        return -1;
    }

    fzl::FdioCaller caller{fbl::unique_fd(fd)};
    zx_status_t status = parse_rpt_descriptor(caller, argv[0]);
    return static_cast<int>(status);
}

int main(int argc, const char** argv) {
    if (argc < 2) {
        usage();
        return 0;
    }
    argc--;
    argv++;
    if (!strcmp("-v", argv[0])) {
        verbose = true;
        argc--;
        argv++;
    }
    if (!strcmp("read", argv[0])) {
        if (argc > 1) {
            return read_reports(argc, argv);
        } else {
            return readall_reports(argc, argv);
        }
    }

    if (!strcmp("get", argv[0])) {
        return get_report(argc, argv);
    }

    if (!strcmp("set", argv[0])) {
        return set_report(argc, argv);
    }

    if (!strcmp("parse", argv[0])) {
        return parse(argc, argv);
    }

    usage();
    return 0;
}
