/*
 * Copyright 2016 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "base/container_of.h"
#include "base/fwdb.h"
#include "base/init_funcs.h"
#include "base/keycodes.h"
#include "base/list.h"
#include "drivers/console/console.h"
#include "uefi/uefi.h"

#include <stdio.h>
#include <string.h>

EFI_GUID simple_text_input_ex_protocol_guid =
	EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;

typedef struct {
	Console console;

	DcEvent exit_bs;

	EFI_KEY_DATA last_key;

	EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *con_out;
	EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *con_in;
} UefiConsole;

static void uefi_console_write(ConsoleOutputOps *me,
			       const void *buffer, size_t count)
{
	UefiConsole *uefi = container_of(me, UefiConsole, console.output);

	uint16_t output[0x100];
	const uint8_t *input = buffer;

	const size_t space = 0x100;
	size_t out = 0;
	size_t in = 0;
	while (in < count) {
		// If we're out of room, flush the output buffer. Never start
		// converting a character with only one or two output slots
		// left. If it's a newline and we need to inject a carriage
		// return, and we need a place for the NULL terminator.
		if (space - out < 3) {
			output[out++] = '\0';
			uefi->con_out->OutputString(uefi->con_out, output);
			out = 0;
		}

		// Grab a character from the input buffer.
		uint8_t in_char = input[in++];

		// Stuff it into the output buffer.
		output[out++] = in_char;
		// If it was a newline, add a carriage return.
		if (in_char == '\n')
			output[out++] = '\r';
	}
	// Flush any leftovers from the output buffer.
	if (out) {
		output[out++] = '\0';
		uefi->con_out->OutputString(uefi->con_out, output);
	}
}

static int uefi_console_have_key(ConsoleInputOps *me)
{
	UefiConsole *uefi = container_of(me, UefiConsole,
					 console.trusted_input);

	if (!uefi->last_key.Key.ScanCode && !uefi->last_key.Key.UnicodeChar) {
		EFI_KEY_DATA key;
		if (uefi->con_in->ReadKeyStrokeEx(uefi->con_in, &key) !=
		    EFI_NOT_READY) {
			memcpy(&uefi->last_key, &key, sizeof(key));
		}
	}

	return uefi->last_key.Key.ScanCode || uefi->last_key.Key.UnicodeChar;
}

static int uefi_console_get_char(ConsoleInputOps *me)
{
	UefiConsole *uefi = container_of(me, UefiConsole,
					 console.trusted_input);

	while (!me->havekey(me))
	{;}

	uint16_t key = 0;
	switch (uefi->last_key.Key.ScanCode) {
	case 0x1:
		key = KEY_UP;
		break;
	case 0x2:
		key = KEY_DOWN;
		break;
	case 0x3:
		key = KEY_RIGHT;
		break;
	case 0x4:
		key = KEY_LEFT;
		break;
	default:
		key = uefi->last_key.Key.UnicodeChar;
	}

	UINT32 shift_state = uefi->last_key.KeyState.KeyShiftState;
	if ((shift_state & EFI_SHIFT_STATE_VALID) &&
	    (shift_state & (EFI_RIGHT_CONTROL_PRESSED |
			    EFI_LEFT_CONTROL_PRESSED))) {
		if (key >= 'a' && key <= 'z')
			key = key & 0x1f;
		else
			key = 0;
	}

	memset(&uefi->last_key, 0, sizeof(uefi->last_key));

	return key;
}

static int uefi_console_disable(DcEvent *event)
{
	UefiConsole *uefi = container_of(event, UefiConsole, exit_bs);
	list_remove(&uefi->console.list_node);
	return 0;
}

static int uefi_console_init(void)
{
	EFI_SYSTEM_TABLE *sys = uefi_system_table_ptr();
	if (!sys)
		return 1;

	static UefiConsole uefi = {
		.console = {
			.output = {
				.write = &uefi_console_write
			},

			// There isn't a way to distinguish where input came
			// from, so lets just trust everything when on UEFI.
			.trusted_input = {
				.havekey = &uefi_console_have_key,
				.getchar = &uefi_console_get_char,
			},
		},
		.exit_bs = {
			.trigger = &uefi_console_disable
		},
	};

	uefi.con_out = sys->ConOut;

	EFI_BOOT_SERVICES *bs = sys->BootServices;
	EFI_STATUS status = bs->HandleProtocol(
		sys->ConsoleInHandle, &simple_text_input_ex_protocol_guid,
		(void **)&uefi.con_in);
	if (status != EFI_SUCCESS) {
		printf("Failed to retrieve console input ex protocol.\n");
		return 1;
	}

	list_insert_after(&uefi.console.list_node, &console_list);
	uefi_add_exit_boot_services_event(&uefi.exit_bs);

	return 0;
}

INIT_FUNC_CONSOLE(uefi_console_init)
