/*
 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/console.h>
#include <ipxe/keys.h>
#include <ipxe/keymap.h>
#include <ipxe/usb.h>
#include "usbkbd.h"

/** @file
 *
 * USB keyboard driver
 *
 */

/** List of USB keyboards */
static LIST_HEAD ( usb_keyboards );

/******************************************************************************
 *
 * Keyboard map
 *
 ******************************************************************************
 */

/**
 * Map USB keycode to iPXE key
 *
 * @v keycode		Keycode
 * @v modifiers		Modifiers
 * @v leds		LED state
 * @ret key		iPXE key
 *
 * Key codes are defined in the USB HID Usage Tables Keyboard/Keypad
 * page.
 */
static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
				 unsigned int leds ) {
	unsigned int key;

	if ( keycode < USBKBD_KEY_A ) {
		/* Not keys */
		key = 0;
	} else if ( keycode <= USBKBD_KEY_Z ) {
		/* Alphabetic keys */
		key = ( keycode - USBKBD_KEY_A + 'a' );
		if ( modifiers & USBKBD_SHIFT ) {
			key -= ( 'a' - 'A' );
		}
	} else if ( keycode <= USBKBD_KEY_0 ) {
		/* Numeric key row */
		if ( modifiers & USBKBD_SHIFT ) {
			key = "!@#$%^&*()" [ keycode - USBKBD_KEY_1 ];
		} else {
			key = ( ( ( keycode - USBKBD_KEY_1 + 1 ) % 10 ) + '0' );
		}
	} else if ( keycode <= USBKBD_KEY_SPACE ) {
		/* Unmodifiable keys */
		static const uint8_t unmodifable[] =
			{ LF, ESC, BACKSPACE, TAB, ' ' };
		key = unmodifable[ keycode - USBKBD_KEY_ENTER ];
	} else if ( keycode <= USBKBD_KEY_SLASH ) {
		/* Punctuation keys */
		if ( modifiers & USBKBD_SHIFT ) {
			key = "_+{}|~:\"~<>?" [ keycode - USBKBD_KEY_MINUS ];
		} else {
			key = "-=[]\\#;'`,./" [ keycode - USBKBD_KEY_MINUS ];
		}
	} else if ( keycode <= USBKBD_KEY_UP ) {
		/* Special keys */
		static const uint16_t special[] = {
			0, 0, 0, 0, 0, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
			KEY_F10, KEY_F11, KEY_F12, 0, 0, 0, KEY_IC, KEY_HOME,
			KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT,
			KEY_LEFT, KEY_DOWN, KEY_UP
		};
		key = special[ keycode - USBKBD_KEY_CAPS_LOCK ];
	} else if ( keycode <= USBKBD_KEY_PAD_ENTER ) {
		/* Keypad (unaffected by Num Lock) */
		key = "\0/*-+\n" [ keycode - USBKBD_KEY_NUM_LOCK ];
	} else if ( keycode <= USBKBD_KEY_PAD_DOT ) {
		/* Keypad (affected by Num Lock) */
		if ( leds & USBKBD_LED_NUM_LOCK ) {
			key = "1234567890." [ keycode - USBKBD_KEY_PAD_1 ];
		} else {
			static const uint16_t keypad[] = {
				KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, 0,
				KEY_RIGHT, KEY_HOME, KEY_UP, KEY_PPAGE,
				KEY_IC, KEY_DC
			};
			key = keypad[ keycode - USBKBD_KEY_PAD_1 ];
		};
	} else if ( keycode == USBKBD_KEY_NON_US ) {
		/* Non-US \ and | */
		key = ( ( modifiers & USBKBD_SHIFT ) ?
			( KEYMAP_PSEUDO | '|' ) : ( KEYMAP_PSEUDO | '\\' ) );
	} else {
		key = 0;
	}

	/* Remap key if applicable */
	if ( ( keycode < USBKBD_KEY_CAPS_LOCK ) ||
	     ( keycode == USBKBD_KEY_NON_US ) ) {

		/* Apply modifiers */
		if ( modifiers & USBKBD_CTRL )
			key |= KEYMAP_CTRL;
		if ( modifiers & USBKBD_ALT_RIGHT )
			key |= KEYMAP_ALTGR;
		if ( leds & USBKBD_LED_CAPS_LOCK )
			key |= KEYMAP_CAPSLOCK;

		/* Remap key */
		key = key_remap ( key );
	}

	return key;
}

/******************************************************************************
 *
 * Keyboard buffer
 *
 ******************************************************************************
 */

/**
 * Insert keypress into keyboard buffer
 *
 * @v kbd		USB keyboard
 * @v keycode		Keycode
 * @v modifiers		Modifiers
 */
static void usbkbd_produce ( struct usb_keyboard *kbd, unsigned int keycode,
			     unsigned int modifiers ) {
	unsigned int leds = 0;
	unsigned int key;

	/* Check for LED-modifying keys */
	if ( keycode == USBKBD_KEY_CAPS_LOCK ) {
		leds = USBKBD_LED_CAPS_LOCK;
	} else if ( keycode == USBKBD_KEY_NUM_LOCK ) {
		leds = USBKBD_LED_NUM_LOCK;
	}

	/* Handle LED-modifying keys */
	if ( leds ) {
		kbd->leds ^= leds;
		kbd->leds_changed = 1;
		return;
	}

	/* Map to iPXE key */
	key = usbkbd_map ( keycode, modifiers, kbd->leds );

	/* Do nothing if this keycode has no corresponding iPXE key */
	if ( ! key ) {
		DBGC ( kbd, "KBD %s has no key for keycode %#02x:%#02x\n",
		       kbd->name, modifiers, keycode );
		return;
	}

	/* Check for buffer overrun */
	if ( usbkbd_fill ( kbd ) >= USBKBD_BUFSIZE ) {
		DBGC ( kbd, "KBD %s buffer overrun (key %#02x)\n",
		       kbd->name, key );
		return;
	}

	/* Insert into buffer */
	kbd->key[ ( kbd->prod++ ) % USBKBD_BUFSIZE ] = key;
	DBGC2 ( kbd, "KBD %s key %#02x produced\n", kbd->name, key );
}

/**
 * Consume character from keyboard buffer
 *
 * @v kbd		USB keyboard
 * @ret character	Character
 */
static unsigned int usbkbd_consume ( struct usb_keyboard *kbd ) {
	static char buf[] = "\x1b[xx~";
	char *tmp = &buf[2];
	unsigned int key;
	unsigned int character;
	unsigned int ansi_n;
	unsigned int len;

	/* Sanity check */
	assert ( usbkbd_fill ( kbd ) > 0 );

	/* Get current keypress */
	key = kbd->key[ kbd->cons % USBKBD_BUFSIZE ];

	/* If this is a straightforward key, just consume and return it */
	if ( key < KEY_MIN ) {
		kbd->cons++;
		DBGC2 ( kbd, "KBD %s key %#02x consumed\n", kbd->name, key );
		return key;
	}

	/* Construct ANSI sequence */
	ansi_n = KEY_ANSI_N ( key );
	if ( ansi_n )
		tmp += sprintf ( tmp, "%d", ansi_n );
	*(tmp++) = KEY_ANSI_TERMINATOR ( key );
	*tmp = '\0';
	len = ( tmp - buf );
	assert ( len < sizeof ( buf ) );
	if ( kbd->subcons == 0 ) {
		DBGC2 ( kbd, "KBD %s key %#02x consumed as ^[%s\n",
			kbd->name, key, &buf[1] );
	}

	/* Extract character from ANSI sequence */
	assert ( kbd->subcons < len );
	character = buf[ kbd->subcons++ ];

	/* Consume key if applicable */
	if ( kbd->subcons == len ) {
		kbd->cons++;
		kbd->subcons = 0;
	}

	return character;
}

/******************************************************************************
 *
 * Keyboard report
 *
 ******************************************************************************
 */

/**
 * Check for presence of keycode in report
 *
 * @v report		Keyboard report
 * @v keycode		Keycode (must be non-zero)
 * @ret has_keycode	Keycode is present in report
 */
static int usbkbd_has_keycode ( struct usb_keyboard_report *report,
				unsigned int keycode ) {
	unsigned int i;

	/* Check for keycode */
	for ( i = 0 ; i < ( sizeof ( report->keycode ) /
			    sizeof ( report->keycode[0] ) ) ; i++ ) {
		if ( report->keycode[i] == keycode )
			return keycode;
	}

	return 0;
}

/**
 * Handle keyboard report
 *
 * @v kbd		USB keyboard
 * @v new		New keyboard report
 */
static void usbkbd_report ( struct usb_keyboard *kbd,
			    struct usb_keyboard_report *new ) {
	struct usb_keyboard_report *old = &kbd->report;
	unsigned int keycode;
	unsigned int i;

	/* Check if current key has been released */
	if ( kbd->keycode && ! usbkbd_has_keycode ( new, kbd->keycode ) ) {
		DBGC2 ( kbd, "KBD %s keycode %#02x released\n",
			kbd->name, kbd->keycode );
		kbd->keycode = 0;
	}

	/* Decrement auto-repeat hold-off timer, if applicable */
	if ( kbd->holdoff )
		kbd->holdoff--;

	/* Check if a new key has been pressed */
	for ( i = 0 ; i < ( sizeof ( new->keycode ) /
			    sizeof ( new->keycode[0] ) ) ; i++ ) {

		/* Ignore keys present in the previous report */
		keycode = new->keycode[i];
		if ( ( keycode == 0 ) || usbkbd_has_keycode ( old, keycode ) )
			continue;
		DBGC2 ( kbd, "KBD %s keycode %#02x pressed\n",
			kbd->name, keycode );

		/* Insert keypress into keyboard buffer */
		usbkbd_produce ( kbd, keycode, new->modifiers );

		/* Record as most recent keycode */
		kbd->keycode = keycode;

		/* Start auto-repeat hold-off timer */
		kbd->holdoff = USBKBD_HOLDOFF;
	}

	/* Insert auto-repeated keypress into keyboard buffer, if applicable */
	if ( kbd->keycode && ! kbd->holdoff )
		usbkbd_produce ( kbd, kbd->keycode, new->modifiers );

	/* Record report */
	memcpy ( old, new, sizeof ( *old ) );
}

/******************************************************************************
 *
 * Interrupt endpoint
 *
 ******************************************************************************
 */

/**
 * Complete interrupt transfer
 *
 * @v ep		USB endpoint
 * @v iobuf		I/O buffer
 * @v rc		Completion status code
 */
static void usbkbd_complete ( struct usb_endpoint *ep,
			      struct io_buffer *iobuf, int rc ) {
	struct usb_keyboard *kbd = container_of ( ep, struct usb_keyboard,
						  hid.in );
	struct usb_keyboard_report *report;

	/* Ignore packets cancelled when the endpoint closes */
	if ( ! ep->open )
		goto drop;

	/* Ignore packets with errors */
	if ( rc != 0 ) {
		DBGC ( kbd, "KBD %s interrupt IN failed: %s\n",
		       kbd->name, strerror ( rc ) );
		goto drop;
	}

	/* Ignore underlength packets */
	if ( iob_len ( iobuf ) < sizeof ( *report ) ) {
		DBGC ( kbd, "KBD %s underlength report:\n", kbd->name );
		DBGC_HDA ( kbd, 0, iobuf->data, iob_len ( iobuf ) );
		goto drop;
	}
	report = iobuf->data;

	/* Handle keyboard report */
	usbkbd_report ( kbd, report );

 drop:
	/* Recycle I/O buffer */
	usb_recycle ( &kbd->hid.in, iobuf );
}

/** Interrupt endpoint operations */
static struct usb_endpoint_driver_operations usbkbd_operations = {
	.complete = usbkbd_complete,
};

/******************************************************************************
 *
 * Keyboard LEDs
 *
 ******************************************************************************
 */

/**
 * Set keyboard LEDs
 *
 * @v kbd		USB keyboard
 * @ret rc		Return status code
 */
static int usbkbd_set_leds ( struct usb_keyboard *kbd ) {
	struct usb_function *func = kbd->hid.func;
	int rc;

	DBGC2 ( kbd, "KBD %s setting LEDs to %#02x\n", kbd->name, kbd->leds );

	/* Set keyboard LEDs */
	if ( ( rc = usbhid_set_report ( func->usb, func->interface[0],
					USBHID_REPORT_OUTPUT, 0, &kbd->leds,
					sizeof ( kbd->leds ) ) ) != 0 ) {
		DBGC ( kbd, "KBD %s could not set LEDs to %#02x: %s\n",
		       kbd->name, kbd->leds, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/******************************************************************************
 *
 * USB interface
 *
 ******************************************************************************
 */

/**
 * Probe device
 *
 * @v func		USB function
 * @v config		Configuration descriptor
 * @ret rc		Return status code
 */
static int usbkbd_probe ( struct usb_function *func,
			  struct usb_configuration_descriptor *config ) {
	struct usb_device *usb = func->usb;
	struct usb_keyboard *kbd;
	int rc;

	/* Allocate and initialise structure */
	kbd = zalloc ( sizeof ( *kbd ) );
	if ( ! kbd ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	kbd->name = func->name;
	kbd->bus = usb->port->hub->bus;
	usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
	usb_refill_init ( &kbd->hid.in, 0, sizeof ( kbd->report ),
			  USBKBD_INTR_MAX_FILL );

	/* Describe USB human interface device */
	if ( ( rc = usbhid_describe ( &kbd->hid, config ) ) != 0 ) {
		DBGC ( kbd, "KBD %s could not describe: %s\n",
		       kbd->name, strerror ( rc ) );
		goto err_describe;
	}
	DBGC ( kbd, "KBD %s using %s (len %zd)\n",
	       kbd->name, usb_endpoint_name ( &kbd->hid.in ), kbd->hid.in.mtu );

	/* Set boot protocol */
	if ( ( rc = usbhid_set_protocol ( usb, func->interface[0],
					  USBHID_PROTOCOL_BOOT ) ) != 0 ) {
		DBGC ( kbd, "KBD %s could not set boot protocol: %s\n",
		       kbd->name, strerror ( rc ) );
		goto err_set_protocol;
	}

	/* Set idle time */
	if ( ( rc = usbhid_set_idle ( usb, func->interface[0], 0,
				      USBKBD_IDLE_DURATION ) ) != 0 ) {
		DBGC ( kbd, "KBD %s could not set idle time: %s\n",
		       kbd->name, strerror ( rc ) );
		goto err_set_idle;
	}

	/* Open USB human interface device */
	if ( ( rc = usbhid_open ( &kbd->hid ) ) != 0 ) {
		DBGC ( kbd, "KBD %s could not open: %s\n",
		       kbd->name, strerror ( rc ) );
		goto err_open;
	}

	/* Add to list of USB keyboards */
	list_add_tail ( &kbd->list, &usb_keyboards );

	/* Set initial LED state */
	usbkbd_set_leds ( kbd );

	usb_func_set_drvdata ( func, kbd );
	return 0;

	usbhid_close ( &kbd->hid );
 err_open:
 err_set_idle:
 err_set_protocol:
 err_describe:
	free ( kbd );
 err_alloc:
	return rc;
}

/**
 * Remove device
 *
 * @v func		USB function
 */
static void usbkbd_remove ( struct usb_function *func ) {
	struct usb_keyboard *kbd = usb_func_get_drvdata ( func );

	/* Remove from list of USB keyboards */
	list_del ( &kbd->list );

	/* Close USB human interface device */
	usbhid_close ( &kbd->hid );

	/* Free device */
	free ( kbd );
}

/** USB keyboard device IDs */
static struct usb_device_id usbkbd_ids[] = {
	{
		.name = "kbd",
		.vendor = USB_ANY_ID,
		.product = USB_ANY_ID,
	},
};

/** USB keyboard driver */
struct usb_driver usbkbd_driver __usb_driver = {
	.ids = usbkbd_ids,
	.id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
	.class = USB_CLASS_ID ( USB_CLASS_HID, USB_SUBCLASS_HID_BOOT,
				USBKBD_PROTOCOL ),
	.score = USB_SCORE_NORMAL,
	.probe = usbkbd_probe,
	.remove = usbkbd_remove,
};

/******************************************************************************
 *
 * Console interface
 *
 ******************************************************************************
 */

/**
 * Read a character from the console
 *
 * @ret character	Character read
 */
static int usbkbd_getchar ( void ) {
	struct usb_keyboard *kbd;

	/* Consume first available key */
	list_for_each_entry ( kbd, &usb_keyboards, list ) {
		if ( usbkbd_fill ( kbd ) )
			return usbkbd_consume ( kbd );
	}

	return 0;
}

/**
 * Check for available input
 *
 * @ret is_available	Input is available
 */
static int usbkbd_iskey ( void ) {
	struct usb_keyboard *kbd;
	unsigned int fill;

	/* Poll USB keyboards, refill endpoints, and set LEDs if applicable */
	list_for_each_entry ( kbd, &usb_keyboards, list ) {

		/* Poll keyboard */
		usb_poll ( kbd->bus );

		/* Refill endpoints */
		usb_refill ( &kbd->hid.in );

		/* Update keyboard LEDs, if applicable */
		if ( kbd->leds_changed ) {
			usbkbd_set_leds ( kbd );
			kbd->leds_changed = 0;
		}
	}

	/* Check for a non-empty keyboard buffer */
	list_for_each_entry ( kbd, &usb_keyboards, list ) {
		fill = usbkbd_fill ( kbd );
		if ( fill )
			return fill;
	}

	return 0;
}

/** USB keyboard console */
struct console_driver usbkbd_console __console_driver = {
	.getchar = usbkbd_getchar,
	.iskey = usbkbd_iskey,
};
