/*
 * 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 = 500 + len * 8;
    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 = 500 + len * 8;
    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 if (errno != ERROR_SEM_TIMEOUT) {
                // 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 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;
    }

    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);
}
