/*
 * 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 unsigned int 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 unsigned int 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,
};
