/*
 * Haiku Backend for libusb
 * Copyright © 2014 Akshay Jaggi <akshay1994.leo@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */


#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <new>
#include <vector>

#include "haiku_usb.h"

USBRoster gUsbRoster;
int32 gInitCount = 0;

static int haiku_get_config_descriptor(struct libusb_device *, uint8_t,
    unsigned char *, size_t, int *);

static int
haiku_init(struct libusb_context *ctx)
{
	if (atomic_add(&gInitCount, 1) == 0)
		return gUsbRoster.Start();
	return LIBUSB_SUCCESS;
}

static void
haiku_exit(struct libusb_context *ctx)
{
	UNUSED(ctx);
	if (atomic_add(&gInitCount, -1) == 1)
		gUsbRoster.Stop();
}

static int
haiku_open(struct libusb_device_handle *dev_handle)
{
	USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv);
	USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev);
	if (handle == NULL)
		return LIBUSB_ERROR_NO_MEM;
	if (handle->InitCheck() == false) {
		delete handle;
		return LIBUSB_ERROR_NO_DEVICE;
	}
	*((USBDeviceHandle **)dev_handle->os_priv) = handle;
	return LIBUSB_SUCCESS;
}

static void
haiku_close(struct libusb_device_handle *dev_handle)
{
	USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
	if (handle == NULL)
		return;
	delete handle;
	*((USBDeviceHandle **)dev_handle->os_priv) = NULL;
}

static int
haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian)
{
	USBDevice *dev = *((USBDevice **)device->os_priv);
	memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH);
	*host_endian = 0;
	return LIBUSB_SUCCESS;
}

static int
haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian)
{
	USBDevice *dev = *((USBDevice **)device->os_priv);
	return haiku_get_config_descriptor(device, dev->ActiveConfigurationIndex(), buffer, len, host_endian);
}

static int
haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
{
	USBDevice *dev = *((USBDevice **)device->os_priv);
	const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index);
	if (config == NULL) {
		usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor");
		return LIBUSB_ERROR_INVALID_PARAM;
	}
	if (len > config->total_length) {
		len = config->total_length;
	}
	memcpy(buffer, config, len);
	*host_endian = 0;
	return len;
}

static int
haiku_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
	USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv);
	return handle->SetConfiguration(config);
}

static int
haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
	USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
	return handle->ClaimInterface(interface_number);
}

static int
haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting)
{
	USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
	return handle->SetAltSetting(interface_number, altsetting);
}

static int
haiku_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
	return handle->ClearHalt(endpoint);
}

static int
haiku_reset_device(struct libusb_device_handle *dev_handle)
{
	/* TODO */
	return LIBUSB_ERROR_NOT_SUPPORTED;
}

static int
haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
	USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
	haiku_set_altsetting(dev_handle,interface_number, 0);
	return handle->ReleaseInterface(interface_number);
}

static int
haiku_submit_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
	return fDeviceHandle->SubmitTransfer(itransfer);
}

static int
haiku_cancel_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
	return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)));
}

static void
haiku_clear_transfer_priv(struct usbi_transfer *itransfer)
{
	USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
	delete transfer;
	*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
}

static int
haiku_handle_transfer_completion(struct usbi_transfer *itransfer)
{
	USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));

	usbi_mutex_lock(&itransfer->lock);
	if (transfer->IsCancelled()) {
		delete transfer;
		*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
		usbi_mutex_unlock(&itransfer->lock);
		if (itransfer->transferred < 0)
			itransfer->transferred = 0;
		return usbi_handle_transfer_cancellation(itransfer);
	}
	libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED;
	if (itransfer->transferred < 0) {
		usbi_err(ITRANSFER_CTX(itransfer), "error in transfer");
		status = LIBUSB_TRANSFER_ERROR;
		itransfer->transferred = 0;
	}
	delete transfer;
	*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
	usbi_mutex_unlock(&itransfer->lock);
	return usbi_handle_transfer_completion(itransfer, status);
}

static int
haiku_clock_gettime(int clkid, struct timespec *tp)
{
	if (clkid == USBI_CLOCK_REALTIME)
		return clock_gettime(CLOCK_REALTIME, tp);
	if (clkid == USBI_CLOCK_MONOTONIC)
		return clock_gettime(CLOCK_MONOTONIC, tp);
	return LIBUSB_ERROR_INVALID_PARAM;
}

const struct usbi_os_backend usbi_backend = {
	.name = "Haiku usbfs",
	.caps = 0,
	.init = haiku_init,
	.exit = haiku_exit,
	.set_option = NULL,
	.get_device_list = NULL,
	.hotplug_poll = NULL,
	.wrap_sys_device = NULL,
	.open = haiku_open,
	.close = haiku_close,
	.get_device_descriptor = haiku_get_device_descriptor,
	.get_active_config_descriptor = haiku_get_active_config_descriptor,
	.get_config_descriptor = haiku_get_config_descriptor,
	.get_config_descriptor_by_value = NULL,


	.get_configuration = NULL,
	.set_configuration = haiku_set_configuration,
	.claim_interface = haiku_claim_interface,
	.release_interface = haiku_release_interface,

	.set_interface_altsetting = haiku_set_altsetting,
	.clear_halt = haiku_clear_halt,
	.reset_device = haiku_reset_device,

	.alloc_streams = NULL,
	.free_streams = NULL,

	.dev_mem_alloc = NULL,
	.dev_mem_free = NULL,

	.kernel_driver_active = NULL,
	.detach_kernel_driver = NULL,
	.attach_kernel_driver = NULL,

	.destroy_device = NULL,

	.submit_transfer = haiku_submit_transfer,
	.cancel_transfer = haiku_cancel_transfer,
	.clear_transfer_priv = haiku_clear_transfer_priv,

	.handle_events = NULL,
	.handle_transfer_completion = haiku_handle_transfer_completion,

	.clock_gettime = haiku_clock_gettime,

#ifdef USBI_TIMERFD_AVAILABLE
	.get_timerfd_clockid = NULL,
#endif

	.context_priv_size = 0,
	.device_priv_size = sizeof(USBDevice *),
	.device_handle_priv_size = sizeof(USBDeviceHandle *),
	.transfer_priv_size = sizeof(USBTransfer *),
};
