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

#define DT_DRV_COMPAT input_keymap

#include <zephyr/device.h>
#include <zephyr/dt-bindings/input/keymap.h>
#include <zephyr/input/input.h>
#include <zephyr/input/input_keymap.h>
#include <zephyr/kernel.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(input_keymap, CONFIG_INPUT_LOG_LEVEL);

struct keymap_config {
	const struct device *input_dev;
	const uint16_t *codes;
	uint32_t num_codes;
	uint8_t row_size;
	uint8_t col_size;
};

struct keymap_data {
	uint32_t row;
	uint32_t col;
	bool pressed;
};

static void keymap_cb(struct input_event *evt, void *user_data)
{
	const struct device *dev = user_data;
	const struct keymap_config *cfg = dev->config;
	struct keymap_data *data = dev->data;
	const uint16_t *codes = cfg->codes;
	uint32_t offset;

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

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

	if (data->row >= cfg->row_size ||
	    data->col >= cfg->col_size) {
		LOG_WRN("keymap event out of range: row=%u col=%u", data->row, data->col);
		return;
	}

	offset = (data->row * cfg->col_size) + data->col;

	if (offset >= cfg->num_codes || codes[offset] == 0) {
		LOG_DBG("keymap event undefined: row=%u col=%u", data->row, data->col);
		return;
	}

	LOG_DBG("input event: %3u %3u %d", data->row, data->col, data->pressed);

	input_report_key(dev, codes[offset], data->pressed, true, K_FOREVER);
}

static int keymap_init(const struct device *dev)
{
	const struct keymap_config *cfg = dev->config;

	if (!device_is_ready(cfg->input_dev)) {
		LOG_ERR("input device not ready");
		return -ENODEV;
	}

	return 0;
}

#define KEYMAP_ENTRY_OFFSET(keymap_entry, col_size) \
	(MATRIX_ROW(keymap_entry) * col_size + MATRIX_COL(keymap_entry))

#define KEYMAP_ENTRY_CODE(keymap_entry) (keymap_entry & 0xffff)

#define KEYMAP_ENTRY_VALIDATE(node_id, prop, idx)			\
	BUILD_ASSERT(MATRIX_ROW(DT_PROP_BY_IDX(node_id, prop, idx)) <	\
		     DT_PROP(node_id, row_size), "invalid row");	\
	BUILD_ASSERT(MATRIX_COL(DT_PROP_BY_IDX(node_id, prop, idx)) <	\
		     DT_PROP(node_id, col_size), "invalid col");

#define CODES_INIT(node_id, prop, idx) \
	[KEYMAP_ENTRY_OFFSET(DT_PROP_BY_IDX(node_id, prop, idx), DT_PROP(node_id, col_size))] = \
		KEYMAP_ENTRY_CODE(DT_PROP_BY_IDX(node_id, prop, idx)),

#define INPUT_KEYMAP_DEFINE(inst)								\
	INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(DT_INST_PARENT(inst)), keymap_cb,		\
				    (void *)DEVICE_DT_INST_GET(inst), keymap_cb_##inst);	\
												\
	DT_INST_FOREACH_PROP_ELEM(inst, keymap, KEYMAP_ENTRY_VALIDATE)				\
												\
	static const uint16_t keymap_codes_##inst[] = {						\
		DT_INST_FOREACH_PROP_ELEM(inst, keymap, CODES_INIT)				\
	};											\
												\
	static const struct keymap_config keymap_config_##inst = {				\
		.input_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)),				\
		.codes = keymap_codes_##inst,							\
		.num_codes = ARRAY_SIZE(keymap_codes_##inst),					\
		.row_size = DT_INST_PROP(inst, row_size),					\
		.col_size = DT_INST_PROP(inst, col_size),					\
	};											\
												\
	static struct keymap_data keymap_data_##inst;						\
												\
	DEVICE_DT_INST_DEFINE(inst, keymap_init, NULL,						\
			      &keymap_data_##inst, &keymap_config_##inst,			\
			      POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(INPUT_KEYMAP_DEFINE)
