/*
 * notify.c
 * Copyright (C) 2026 Aitor Cuadrado Zubizarreta <aitor@genuen.org>
 */

#include "notify.h"

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>

#include <libubox/uloop.h>

#ifndef NETAID_NOTIFY_PIDFILE
#define NETAID_NOTIFY_PIDFILE "/run/netaid/notify.pids"
#endif

#ifndef NETAID_NOTIFY_DIR
#define NETAID_NOTIFY_DIR "/run/netaid"
#endif

#define NOTIFY_DEBOUNCE_MS 150

static struct uloop_timeout notify_timeout;
static int notify_armed;

static void
ensure_notify_dir(void)
{
	struct stat st;

	if (stat(NETAID_NOTIFY_DIR, &st) == 0)
		return;

	if (mkdir(NETAID_NOTIFY_DIR, 0755) != 0 && errno != EEXIST)
		syslog(LOG_WARNING, "netaid: cannot create %s: %s",
		       NETAID_NOTIFY_DIR, strerror(errno));
}

static void
notify_fire_cb(struct uloop_timeout *t)
{
	FILE *f;
	char line[32];
	pid_t pid;

	(void) t;
	notify_armed = 0;

	f = fopen(NETAID_NOTIFY_PIDFILE, "r");
	if (!f)
		return;

	while (fgets(line, sizeof(line), f)) {
		pid = (pid_t) strtol(line, NULL, 10);
		if (pid <= 1)
			continue;
		if (kill(pid, SIGUSR1) != 0 && errno != ESRCH)
			syslog(LOG_DEBUG, "netaid: SIGUSR1 to pid %d: %s",
			       (int) pid, strerror(errno));
	}

	fclose(f);
}

void
netaid_ui_notify_init(void)
{
	memset(&notify_timeout, 0, sizeof(notify_timeout));
	notify_timeout.cb = notify_fire_cb;
	notify_armed = 0;
	ensure_notify_dir();
}

void
netaid_ui_notify_fini(void)
{
	uloop_timeout_cancel(&notify_timeout);
	notify_armed = 0;
}

void
netaid_ui_notify_schedule(void)
{
	notify_armed = 1;
	uloop_timeout_set(&notify_timeout, NOTIFY_DEBOUNCE_MS);
}
