#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/time.h>

#include <event.h>

#define INFO_LOG(x_fmt, x_args...) fprintf(stderr, "%s:%d:" x_fmt "\n", __FILE__, __LINE__, ##x_args)
#define ERROR_LOG(x_fmt, x_args...) fprintf(stderr, "ERROR:%s:%d:" x_fmt "\n", __FILE__, __LINE__, ##x_args)

struct myctx {
	int sig;
	int id;
	struct event evt;
};

static void
sigalrm(int fd, short ev, void *ctx)
{
	struct myctx *m = (struct myctx *)ctx;
	if (ev != EV_SIGNAL) {
		ERROR_LOG("Strange event %d, fd = %d, ctx = %p", ev, fd, ctx);
		return;
	}
	INFO_LOG("Got signal %d id %d for ctx %p", m->sig,m->id, ctx);
}

static int
set_itimer(const int msecs)
{
	int secs = msecs/1000;
	int usecs = msecs*1000 - secs*1000000;
	struct itimerval itv;

	itv.it_interval.tv_sec = 0;
	itv.it_interval.tv_usec = 0;
	itv.it_value.tv_sec = secs;
	itv.it_value.tv_usec = usecs;

	if (setitimer(ITIMER_REAL, &itv, NULL) != 0) {
	       	ERROR_LOG("setitimer: %s\n", strerror(errno));
	       	return (-1);
	}
	return (0);
}

static void
setsigs()
{
	struct myctx *m;

	m = (struct myctx *)malloc(sizeof (struct myctx));
	signal_set(&m->evt, SIGALRM, sigalrm, m);
	signal_add(&m->evt, NULL);
	INFO_LOG("Added ctx %p for sigalrm", m);

	m = (struct myctx *)malloc(sizeof (struct myctx));
	signal_set(&m->evt, SIGALRM, sigalrm, m);
	signal_add(&m->evt, NULL);
	INFO_LOG("Added ctx %p for sigalrm", m);
}

static void
testprog()
{
	int rc;

	event_init();
	setsigs();
	set_itimer(300);
	rc = event_dispatch();
	INFO_LOG("PID %d:event_dispatch() returned %d", getpid(), rc);
	return;
}

static void
usage(const char *cmd)
{
	fprintf(stderr, "Usage: %s [-n nprocs]\n", cmd);
	exit(1);
}

int
main(int argc, char *argv[])
{
	const char *cmd = argv[0];
	int ch;
	int nprocs = 1;

	while ((ch = getopt(argc, argv, "n:")) != -1) {
		switch (ch) {
		case 'n':
			nprocs = atoi(optarg);
			break;
		default:
			usage(cmd);
			break;
		}
	}
	testprog();
	return (0);
}
