/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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 OWNER 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 <windows.h>
#include <winerror.h>
#include <errno.h>
#include <usb100.h>
#include <adb_api.h>
#include <stdio.h>

#include "usb.h"

//#define TRACE_USB 1
#if TRACE_USB
#define DBG(x...) fprintf(stderr, x)
#else
#define DBG(x...)
#endif

#define MAX_USBFS_BULK_SIZE (1024 * 1024)

/** Structure usb_handle describes our connection to the usb device via
  AdbWinApi.dll. This structure is returned from usb_open() routine and
  is expected in each subsequent call that is accessing the device.
*/
struct usb_handle {
    /// Handle to USB interface
    ADBAPIHANDLE  adb_interface;

    /// Handle to USB read pipe (endpoint)
    ADBAPIHANDLE  adb_read_pipe;

    /// Handle to USB write pipe (endpoint)
    ADBAPIHANDLE  adb_write_pipe;

    /// Interface name
    char*         interface_name;
};

/// Class ID assigned to the device by androidusb.sys
static const GUID usb_class_id = ANDROID_USB_CLASS_ID;


/// Checks if interface (device) matches certain criteria
int recognized_device(usb_handle* handle, ifc_match_func callback);

/// Opens usb interface (device) by interface (device) name.
usb_handle* do_usb_open(const wchar_t* interface_name);

/// Writes data to the opened usb handle
int usb_write(usb_handle* handle, const void* data, int len);

/// Reads data using the opened usb handle
int usb_read(usb_handle *handle, void* data, int len);

/// Cleans up opened usb handle
void usb_cleanup_handle(usb_handle* handle);

/// Cleans up (but don't close) opened usb handle
void usb_kick(usb_handle* handle);

/// Closes opened usb handle
int usb_close(usb_handle* handle);


usb_handle* do_usb_open(const wchar_t* interface_name) {
    // Allocate our handle
    usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
    if (NULL == ret)
        return NULL;

    // Create interface.
    ret->adb_interface = AdbCreateInterfaceByName(interface_name);

    if (NULL == ret->adb_interface) {
        free(ret);
        errno = GetLastError();
        return NULL;
    }

    // Open read pipe (endpoint)
    ret->adb_read_pipe =
        AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
                                   AdbOpenAccessTypeReadWrite,
                                   AdbOpenSharingModeReadWrite);
    if (NULL != ret->adb_read_pipe) {
        // Open write pipe (endpoint)
        ret->adb_write_pipe =
            AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
                                      AdbOpenAccessTypeReadWrite,
                                      AdbOpenSharingModeReadWrite);
        if (NULL != ret->adb_write_pipe) {
            // Save interface name
            unsigned long name_len = 0;

            // First get expected name length
            AdbGetInterfaceName(ret->adb_interface,
                          NULL,
                          &name_len,
                          true);
            if (0 != name_len) {
                ret->interface_name = (char*)malloc(name_len);

                if (NULL != ret->interface_name) {
                    // Now save the name
                    if (AdbGetInterfaceName(ret->adb_interface,
                                  ret->interface_name,
                                  &name_len,
                                  true)) {
                        // We're done at this point
                        return ret;
                    }
                } else {
                    SetLastError(ERROR_OUTOFMEMORY);
                }
            }
        }
    }

    // Something went wrong.
    errno = GetLastError();
    usb_cleanup_handle(ret);
    free(ret);
    SetLastError(errno);

    return NULL;
}

int usb_write(usb_handle* handle, const void* data, int len) {
    unsigned long time_out = 5000;
    unsigned long written = 0;
    unsigned count = 0;
    int ret;

    DBG("usb_write %d\n", len);
    if (NULL != handle) {
        // Perform write
        while(len > 0) {
            int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
            ret = AdbWriteEndpointSync(handle->adb_write_pipe,
                                   (void*)data,
                                   (unsigned long)xfer,
                                   &written,
                                   time_out);
            errno = GetLastError();
            DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno);
            if (ret == 0) {
                // assume ERROR_INVALID_HANDLE indicates we are disconnected
                if (errno == ERROR_INVALID_HANDLE)
                usb_kick(handle);
                return -1;
            }

            count += written;
            len -= written;
            data += written;

            if (len == 0)
                return count;
        }
    } else {
        DBG("usb_write NULL handle\n");
        SetLastError(ERROR_INVALID_HANDLE);
    }

    DBG("usb_write failed: %d\n", errno);

    return -1;
}

int usb_read(usb_handle *handle, void* data, int len) {
    unsigned long time_out = 0;
    unsigned long read = 0;
    int ret;

    DBG("usb_read %d\n", len);
    if (NULL != handle) {
        while (1) {
            int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;

	        ret = AdbReadEndpointSync(handle->adb_read_pipe,
	                              (void*)data,
	                              (unsigned long)xfer,
	                              &read,
	                              time_out);
            errno = GetLastError();
            DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno);
            if (ret) {
                return read;
            } else {
                // assume ERROR_INVALID_HANDLE indicates we are disconnected
                if (errno == ERROR_INVALID_HANDLE)
                    usb_kick(handle);
                break;
            }
            // else we timed out - try again
        }
    } else {
        DBG("usb_read NULL handle\n");
        SetLastError(ERROR_INVALID_HANDLE);
    }

    DBG("usb_read failed: %d\n", errno);

    return -1;
}

void usb_cleanup_handle(usb_handle* handle) {
    if (NULL != handle) {
        if (NULL != handle->interface_name)
            free(handle->interface_name);
        if (NULL != handle->adb_write_pipe)
            AdbCloseHandle(handle->adb_write_pipe);
        if (NULL != handle->adb_read_pipe)
            AdbCloseHandle(handle->adb_read_pipe);
        if (NULL != handle->adb_interface)
            AdbCloseHandle(handle->adb_interface);

        handle->interface_name = NULL;
        handle->adb_write_pipe = NULL;
        handle->adb_read_pipe = NULL;
        handle->adb_interface = NULL;
    }
}

void usb_kick(usb_handle* handle) {
    if (NULL != handle) {
        usb_cleanup_handle(handle);
    } else {
        SetLastError(ERROR_INVALID_HANDLE);
        errno = ERROR_INVALID_HANDLE;
    }
}

int usb_close(usb_handle* handle) {
    DBG("usb_close\n");

    if (NULL != handle) {
        // Cleanup handle
        usb_cleanup_handle(handle);
        free(handle);
    }

    return 0;
}

int usb_wait_for_disconnect(usb_handle *usb) {
    /* TODO: Punt for now */
    return 0;
}

int recognized_device(usb_handle* handle, ifc_match_func callback) {
    struct usb_ifc_info info;
    USB_DEVICE_DESCRIPTOR device_desc;
    USB_INTERFACE_DESCRIPTOR interf_desc;

    if (NULL == handle)
        return 0;

    // Check vendor and product id first
    if (!AdbGetUsbDeviceDescriptor(handle->adb_interface,
                                 &device_desc)) {
        return 0;
    }

    // Then check interface properties
    if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface,
                                    &interf_desc)) {
        return 0;
    }

    // Must have two endpoints
    if (2 != interf_desc.bNumEndpoints) {
        return 0;
    }

    info.dev_vendor = device_desc.idVendor;
    info.dev_product = device_desc.idProduct;
    info.dev_class = device_desc.bDeviceClass;
    info.dev_subclass = device_desc.bDeviceSubClass;
    info.dev_protocol = device_desc.bDeviceProtocol;
    info.ifc_class = interf_desc.bInterfaceClass;
    info.ifc_subclass = interf_desc.bInterfaceSubClass;
    info.ifc_protocol = interf_desc.bInterfaceProtocol;
    info.writable = 1;

    // read serial number (if there is one)
    unsigned long serial_number_len = sizeof(info.serial_number);
    if (!AdbGetSerialNumber(handle->adb_interface, info.serial_number,
                    &serial_number_len, true)) {
        info.serial_number[0] = 0;
    }

    info.device_path[0] = 0;

    if (callback(&info) == 0) {
        return 1;
    }

    return 0;
}

static usb_handle *find_usb_device(ifc_match_func callback) {
	usb_handle* handle = NULL;
    char entry_buffer[2048];
    char interf_name[2048];
    AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
    unsigned long entry_buffer_size = sizeof(entry_buffer);
    char* copy_name;

    // Enumerate all present and active interfaces.
    ADBAPIHANDLE enum_handle =
        AdbEnumInterfaces(usb_class_id, true, true, true);

    if (NULL == enum_handle)
        return NULL;

    while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
        // TODO(vchtchetkine): FIXME - temp hack converting wchar_t into char.
        // It would be better to change AdbNextInterface so it will return
        // interface name as single char string.
        const wchar_t* wchar_name = next_interface->device_name;
        for(copy_name = interf_name;
                L'\0' != *wchar_name;
                wchar_name++, copy_name++) {
            *copy_name = (char)(*wchar_name);
        }
        *copy_name = '\0';

        handle = do_usb_open(next_interface->device_name);
        if (NULL != handle) {
            // Lets see if this interface (device) belongs to us
            if (recognized_device(handle, callback)) {
                // found it!
                break;
            } else {
                usb_cleanup_handle(handle);
                free(handle);
                handle = NULL;
            }
        }

        entry_buffer_size = sizeof(entry_buffer);
    }

    AdbCloseHandle(enum_handle);
    return handle;
}

usb_handle *usb_open(ifc_match_func callback)
{
    return find_usb_device(callback);
}

// called from fastboot.c
void sleep(int seconds)
{
    Sleep(seconds * 1000);
}
