/*
 * Copyright 2023 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/input/input.h>
#ifdef CONFIG_INPUT_SHELL_KBD_MATRIX_STATE
#include <zephyr/input/input_kbd_matrix.h>
#endif
#include <zephyr/logging/log.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/atomic.h>

LOG_MODULE_DECLARE(input);

#ifdef CONFIG_INPUT_EVENT_DUMP
#ifdef CONFIG_INPUT_SHELL
static atomic_t dump_enable;

static bool input_dump_enabled(void)
{
	return atomic_get(&dump_enable);
}

static int input_cmd_dump(const struct shell *sh, size_t argc, char *argv[])
{
	bool enabled;
	int err = 0;

	enabled = shell_strtobool(argv[1], 0, &err);
	if (err) {
		shell_error(sh, "Invalid argument: %s", argv[1]);
		return err;
	}

	if (enabled) {
		shell_info(sh, "Input event dumping enabled");
		atomic_set(&dump_enable, 1);
	} else {
		atomic_set(&dump_enable, 0);
	}

	return 0;
}
#else
static bool input_dump_enabled(void)
{
	return true;
}
#endif /* CONFIG_INPUT_SHELL */

static void input_cb(struct input_event *evt)
{
	if (!input_dump_enabled()) {
		return;
	}

	LOG_INF("input event: dev=%-16s %3s type=%2x code=%3d value=%d",
		evt->dev ? evt->dev->name : "NULL",
		evt->sync ? "SYN" : "",
		evt->type,
		evt->code,
		evt->value);
}
INPUT_CALLBACK_DEFINE(NULL, input_cb);
#endif /* CONFIG_INPUT_EVENT_DUMP */

#ifdef CONFIG_INPUT_SHELL
static int input_cmd_report(const struct shell *sh, size_t argc, char *argv[])
{
	bool sync;
	int err = 0;
	uint32_t type, code, value;

	if (argc == 5) {
		sync = shell_strtobool(argv[4], 0, &err);
		if (err) {
			shell_error(sh, "Invalid argument: %s", argv[4]);
			return err;
		}
	} else {
		sync = true;
	}

	type = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_error(sh, "Invalid argument: %s", argv[1]);
		return err;
	}
	if (type > UINT8_MAX) {
		shell_error(sh, "Out of range: %s", argv[1]);
		return -EINVAL;
	}

	code = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_error(sh, "Invalid argument: %s", argv[2]);
		return err;
	}
	if (code > UINT16_MAX) {
		shell_error(sh, "Out of range: %s", argv[2]);
		return -EINVAL;
	}

	value = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_error(sh, "Invalid argument: %s", argv[3]);
		return err;
	}

	input_report(NULL, type, code, value, sync, K_FOREVER);

	return 0;
}

#ifdef CONFIG_INPUT_SHELL_KBD_MATRIX_STATE
static const struct device *kbd_matrix_state_dev;
static kbd_row_t kbd_matrix_state[CONFIG_INPUT_SHELL_KBD_MATRIX_STATE_MAX_COLS];
static kbd_row_t kbd_matrix_key_mask[CONFIG_INPUT_SHELL_KBD_MATRIX_STATE_MAX_COLS];

/* Keep space for each column value, 2 char per byte + space. */
#define KEY_MATRIX_ENTRY_LEN (sizeof(kbd_row_t) * 2 + 1)
#define KEY_MATRIX_BUF_SZ (CONFIG_INPUT_SHELL_KBD_MATRIX_STATE_MAX_COLS * \
			   KEY_MATRIX_ENTRY_LEN)
static char kbd_matrix_buf[KEY_MATRIX_BUF_SZ];

static void kbd_matrix_state_log_entry(char *header, kbd_row_t *data)
{
	const struct input_kbd_matrix_common_config *cfg = kbd_matrix_state_dev->config;
	char *buf = kbd_matrix_buf;
	int size = sizeof(kbd_matrix_buf);
	int ret;
	char blank[KEY_MATRIX_ENTRY_LEN];
	int count = 0;

	memset(blank, '-', sizeof(blank) - 1);
	blank[sizeof(blank) - 1] = '\0';

	for (int i = 0; i < cfg->col_size; i++) {
		char *sep = (i + 1) < cfg->col_size ? " " : "";

		if (data[i] != 0) {
			ret = snprintf(buf, size, PRIkbdrow "%s", data[i], sep);
		} else {
			ret = snprintf(buf, size, "%s%s", blank, sep);
		}
		size -= ret;
		buf += ret;

		count += POPCOUNT(data[i]);

		/* Last byte is for the string termination */
		if (size < 1) {
			LOG_ERR("kbd_matrix_buf too small");
			return;
		}
	}

	LOG_INF("%s %s [%s] (%d)",
		kbd_matrix_state_dev->name, header, kbd_matrix_buf, count);
}

static void kbd_matrix_state_log(struct input_event *evt)
{
	const struct input_kbd_matrix_common_config *cfg;
	static uint32_t row, col;
	static bool val;

	if (kbd_matrix_state_dev == NULL || kbd_matrix_state_dev != evt->dev) {
		return;
	}

	cfg = kbd_matrix_state_dev->config;

	switch (evt->code) {
	case INPUT_ABS_X:
		col = evt->value;
		break;
	case INPUT_ABS_Y:
		row = evt->value;
		break;
	case INPUT_BTN_TOUCH:
		val = evt->value;
		break;
	}

	if (!evt->sync) {
		return;
	}

	if (col > (CONFIG_INPUT_SHELL_KBD_MATRIX_STATE_MAX_COLS - 1)) {
		LOG_ERR("column index too large for the state buffer: %d", col);
		return;
	}

	if (col > (cfg->col_size - 1)) {
		LOG_ERR("invalid column index: %d", col);
		return;
	}

	if (row > (cfg->row_size - 1)) {
		LOG_ERR("invalid row index: %d", row);
		return;
	}

	WRITE_BIT(kbd_matrix_state[col], row, val);
	if (val != 0) {
		WRITE_BIT(kbd_matrix_key_mask[col], row, 1);
	}

	kbd_matrix_state_log_entry("state", kbd_matrix_state);
}
INPUT_CALLBACK_DEFINE(NULL, kbd_matrix_state_log);

static int input_cmd_kbd_matrix_state_dump(const struct shell *sh,
					   size_t argc, char *argv[])
{
	const struct device *dev;

	if (!strcmp(argv[1], "off")) {
		if (kbd_matrix_state_dev != NULL) {
			kbd_matrix_state_log_entry("key-mask",
						   kbd_matrix_key_mask);
		}

		kbd_matrix_state_dev = NULL;
		shell_info(sh, "Keyboard state logging disabled");
		return 0;
	}

	dev = device_get_binding(argv[1]);
	if (dev == NULL) {
		shell_error(sh, "Invalid device: %s", argv[1]);
		return -ENODEV;
	}

	if (kbd_matrix_state_dev != NULL && kbd_matrix_state_dev != dev) {
		shell_error(sh, "Already logging for %s, disable logging first",
			    kbd_matrix_state_dev->name);
		return -EINVAL;
	}

	memset(kbd_matrix_state, 0, sizeof(kbd_matrix_state));
	memset(kbd_matrix_key_mask, 0, sizeof(kbd_matrix_state));
	kbd_matrix_state_dev = dev;

	shell_info(sh, "Keyboard state logging enabled for %s", dev->name);

	return 0;
}

static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
	const struct device *dev = shell_device_lookup(idx, NULL);

	entry->syntax = (dev != NULL) ? dev->name : NULL;
	entry->handler = NULL;
	entry->help = NULL;
	entry->subcmd = NULL;
}

SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
#endif /* CONFIG_INPUT_SHELL_KBD_MATRIX_STATE */

SHELL_STATIC_SUBCMD_SET_CREATE(
	sub_input_cmds,
#ifdef CONFIG_INPUT_EVENT_DUMP
	SHELL_CMD_ARG(dump, NULL,
		      "Enable event dumping\n"
		      "usage: dump <on|off>",
		      input_cmd_dump, 2, 0),
#endif /* CONFIG_INPUT_EVENT_DUMP */
#ifdef CONFIG_INPUT_SHELL_KBD_MATRIX_STATE
	SHELL_CMD_ARG(kbd_matrix_state_dump, &dsub_device_name,
		      "Print the state of a keyboard matrix device each time a "
		      "key is pressed or released\n"
		      "usage: kbd_matrix_state_dump <device>|off",
		      input_cmd_kbd_matrix_state_dump, 2, 0),
#endif /* CONFIG_INPUT_SHELL_KBD_MATRIX_STATE */
	SHELL_CMD_ARG(report, NULL,
		      "Trigger an input report event\n"
		      "usage: report <type> <code> <value> [<sync>]",
		      input_cmd_report, 4, 1),
	SHELL_SUBCMD_SET_END);

SHELL_CMD_REGISTER(input, &sub_input_cmds, "Input commands", NULL);
#endif /* CONFIG_INPUT_SHELL */
