/*
 * Copyright (C) 2012 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 <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <time.h>

#include <sys/inotify.h>
#include <linux/hidraw.h>
#include <usbhost/usbhost.h>

#include "f_accessory.h"
#include "accessory.h"

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static int next_id = 1;

static void milli_sleep(int millis) {
    struct timespec tm;

    tm.tv_sec = 0;
    tm.tv_nsec = millis * 1000000;
    nanosleep(&tm, NULL);
}

static void* hid_thread(void* arg) {
    int fd = (int)arg;
    char buffer[4096];
    int id, ret, offset;
    struct usb_device *device;
    struct usb_device_descriptor *device_desc;
    int max_packet;
    struct hidraw_report_descriptor desc;
    int desc_length;

    fprintf(stderr, "hid_thread start fd: %d\n", fd);

    if (ioctl(fd, HIDIOCGRDESCSIZE, &desc_length)) {
        fprintf(stderr, "HIDIOCGRDESCSIZE failed\n");
        close(fd);
        goto err;
    }

    desc.size = HID_MAX_DESCRIPTOR_SIZE - 1;
    if (ioctl(fd, HIDIOCGRDESC, &desc)) {
        fprintf(stderr, "HIDIOCGRDESC failed\n");
        close(fd);
        goto err;
    }

wait_for_device:
    fprintf(stderr, "waiting for device fd: %d\n", fd);
    device = usb_wait_for_device();
    max_packet = usb_device_get_device_descriptor(device)->bMaxPacketSize0;
    // FIXME
    max_packet--;

    // FIXME
    milli_sleep(500);

    pthread_mutex_lock(&mutex);
    id = next_id++;

    ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
            ACCESSORY_REGISTER_HID, id, desc_length, NULL, 0, 1000);
    fprintf(stderr, "ACCESSORY_REGISTER_HID returned %d\n", ret);

    // FIXME
    milli_sleep(500);

    for (offset = 0; offset < desc_length; ) {
        int count = desc_length - offset;
        if (count > max_packet) count = max_packet;

    fprintf(stderr, "sending ACCESSORY_SET_HID_REPORT_DESC offset: %d count: %d desc_length: %d\n",
            offset, count, desc_length);
        ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
                ACCESSORY_SET_HID_REPORT_DESC, id, offset, &desc.value[offset], count, 1000);
    fprintf(stderr, "ACCESSORY_SET_HID_REPORT_DESC returned %d errno %d\n", ret, errno);
        offset += count;
    }

    pthread_mutex_unlock(&mutex);

    while (1) {
        ret = read(fd, buffer, sizeof(buffer));
        if (ret < 0) {
fprintf(stderr, "read failed, errno: %d, fd: %d\n", errno, fd);
            break;
        }

        ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
                    ACCESSORY_SEND_HID_EVENT, id, 0, buffer, ret, 1000);
        if (ret < 0 && errno != EPIPE) {
fprintf(stderr, "ACCESSORY_SEND_HID_EVENT returned %d errno: %d\n", ret, errno);
            goto wait_for_device;
        }
    }

fprintf(stderr, "ACCESSORY_UNREGISTER_HID\n");
    ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
            ACCESSORY_UNREGISTER_HID, id, 0, NULL, 0, 1000);

fprintf(stderr, "hid thread exiting\n");
err:
    return NULL;
}

static void open_hid(const char* name)
{
    char path[100];

    snprintf(path, sizeof(path), "/dev/%s", name);
    int fd = open(path, O_RDWR);
    if (fd < 0) return;

    fprintf(stderr, "opened /dev/%s\n", name);
    pthread_t th;
    pthread_create(&th, NULL, hid_thread, (void *)(uintptr_t)fd);
}

static void* inotify_thread(void* arg)
{
    open_hid("hidraw0");
    open_hid("hidraw1");
    open_hid("hidraw2");
    open_hid("hidraw3");
    open_hid("hidraw4");
    open_hid("hidraw5");
    open_hid("hidraw6");
    open_hid("hidraw7");
    open_hid("hidraw8");
    open_hid("hidraw9");

    int inotify_fd = inotify_init();
    inotify_add_watch(inotify_fd, "/dev", IN_DELETE | IN_CREATE);

    while (1) {
        char event_buf[512];
        struct inotify_event *event;
        int event_pos = 0;
        int event_size;

        int count = read(inotify_fd, event_buf, sizeof(event_buf));
        if (count < (int)sizeof(*event)) {
            if(errno == EINTR)
                continue;
            fprintf(stderr, "could not get event, %s\n", strerror(errno));
            break;
        }
        while (count >= (int)sizeof(*event)) {
            event = (struct inotify_event *)(event_buf + event_pos);
            //fprintf(stderr, "%d: %08x \"%s\"\n", event->wd, event->mask,
            //        event->len ? event->name : "");
            if (event->len) {
                if(event->mask & IN_CREATE) {
                    fprintf(stderr, "created %s\n", event->name);
                    // FIXME
                    milli_sleep(50);
                    open_hid(event->name);
                } else {
                    fprintf(stderr, "lost %s\n", event->name);
                }
            }
            event_size = sizeof(*event) + event->len;
            count -= event_size;
            event_pos += event_size;
        }
    }

    close(inotify_fd);
    return NULL;
}

void init_hid()
{
    pthread_t th;
    pthread_create(&th, NULL, inotify_thread, NULL);
}
