// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2022 Benjamin Tissoires
 *
 * This program will morph the Microsoft Surface Dial into a mouse,
 * and depending on the chosen resolution enable or not the haptic feedback:
 * - a resolution (-r) of 3600 will report 3600 "ticks" in one full rotation
 *   without haptic feedback
 * - any other resolution will report N "ticks" in a full rotation with haptic
 *   feedback
 *
 * A good default for low resolution haptic scrolling is 72 (1 "tick" every 5
 * degrees), and set to 3600 for smooth scrolling.
 */

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>

#include <linux/bpf.h>
#include <linux/errno.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>

#include "hid_surface_dial.skel.h"
#include "hid_bpf_attach.h"

static bool running = true;

struct haptic_syscall_args {
	unsigned int hid;
	int retval;
};

static void int_exit(int sig)
{
	running = false;
	exit(0);
}

static void usage(const char *prog)
{
	fprintf(stderr,
		"%s: %s [OPTIONS] /sys/bus/hid/devices/0BUS:0VID:0PID:00ID\n\n"
		"  OPTIONS:\n"
		"    -r N\t set the given resolution to the device (number of ticks per 360°)\n\n",
		__func__, prog);
	fprintf(stderr,
		"This program will morph the Microsoft Surface Dial into a mouse,\n"
		"and depending on the chosen resolution enable or not the haptic feedback:\n"
		"- a resolution (-r) of 3600 will report 3600 'ticks' in one full rotation\n"
		"  without haptic feedback\n"
		"- any other resolution will report N 'ticks' in a full rotation with haptic\n"
		"  feedback\n"
		"\n"
		"A good default for low resolution haptic scrolling is 72 (1 'tick' every 5\n"
		"degrees), and set to 3600 for smooth scrolling.\n");
}

static int get_hid_id(const char *path)
{
	const char *str_id, *dir;
	char uevent[1024];
	int fd;

	memset(uevent, 0, sizeof(uevent));
	snprintf(uevent, sizeof(uevent) - 1, "%s/uevent", path);

	fd = open(uevent, O_RDONLY | O_NONBLOCK);
	if (fd < 0)
		return -ENOENT;

	close(fd);

	dir = basename((char *)path);

	str_id = dir + sizeof("0003:0001:0A37.");
	return (int)strtol(str_id, NULL, 16);
}

static int attach_prog(struct hid_surface_dial *skel, struct bpf_program *prog, int hid_id)
{
	struct attach_prog_args args = {
		.hid = hid_id,
		.retval = -1,
	};
	int attach_fd, err;
	DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr,
			    .ctx_in = &args,
			    .ctx_size_in = sizeof(args),
	);

	attach_fd = bpf_program__fd(skel->progs.attach_prog);
	if (attach_fd < 0) {
		fprintf(stderr, "can't locate attach prog: %m\n");
		return 1;
	}

	args.prog_fd = bpf_program__fd(prog);
	err = bpf_prog_test_run_opts(attach_fd, &tattr);
	if (err) {
		fprintf(stderr, "can't attach prog to hid device %d: %m (err: %d)\n",
			hid_id, err);
		return 1;
	}
	return 0;
}

static int set_haptic(struct hid_surface_dial *skel, int hid_id)
{
	struct haptic_syscall_args args = {
		.hid = hid_id,
		.retval = -1,
	};
	int haptic_fd, err;
	DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr,
			    .ctx_in = &args,
			    .ctx_size_in = sizeof(args),
	);

	haptic_fd = bpf_program__fd(skel->progs.set_haptic);
	if (haptic_fd < 0) {
		fprintf(stderr, "can't locate haptic prog: %m\n");
		return 1;
	}

	err = bpf_prog_test_run_opts(haptic_fd, &tattr);
	if (err) {
		fprintf(stderr, "can't set haptic configuration to hid device %d: %m (err: %d)\n",
			hid_id, err);
		return 1;
	}
	return 0;
}

int main(int argc, char **argv)
{
	struct hid_surface_dial *skel;
	struct bpf_program *prog;
	const char *optstr = "r:";
	const char *sysfs_path;
	int opt, hid_id, resolution = 72;

	while ((opt = getopt(argc, argv, optstr)) != -1) {
		switch (opt) {
		case 'r':
			{
				char *endp = NULL;
				long l = -1;

				if (optarg) {
					l = strtol(optarg, &endp, 10);
					if (endp && *endp)
						l = -1;
				}

				if (l < 0) {
					fprintf(stderr,
						"invalid r option %s - expecting a number\n",
						optarg ? optarg : "");
					exit(EXIT_FAILURE);
				};

				resolution = (int) l;
				break;
			}
		default:
			usage(basename(argv[0]));
			return 1;
		}
	}

	if (optind == argc) {
		usage(basename(argv[0]));
		return 1;
	}

	sysfs_path = argv[optind];
	if (!sysfs_path) {
		perror("sysfs");
		return 1;
	}

	skel = hid_surface_dial__open_and_load();
	if (!skel) {
		fprintf(stderr, "%s  %s:%d", __func__, __FILE__, __LINE__);
		return -1;
	}

	hid_id = get_hid_id(sysfs_path);
	if (hid_id < 0) {
		fprintf(stderr, "can not open HID device: %m\n");
		return 1;
	}

	skel->data->resolution = resolution;
	skel->data->physical = (int)(resolution / 72);

	bpf_object__for_each_program(prog, *skel->skeleton->obj) {
		/* ignore syscalls */
		if (bpf_program__get_type(prog) != BPF_PROG_TYPE_TRACING)
			continue;

		attach_prog(skel, prog, hid_id);
	}

	signal(SIGINT, int_exit);
	signal(SIGTERM, int_exit);

	set_haptic(skel, hid_id);

	while (running)
		sleep(1);

	hid_surface_dial__destroy(skel);

	return 0;
}
