#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/netmgr.h>
#include <fcntl.h>
#include <errno.h>
#include <ha/ham.h>
#include <sys/procfs.h>

#define NAME_MAX_LEN 20

static struct
{
	procfs_debuginfo info;
	char buf[PATH_MAX];
} proc;

struct process_info
{
	int  pid;
	char name[NAME_MAX_LEN];
};

static void ham_handle(struct process_info *p_info)
{
	int fd;
	char path[PATH_MAX];
	ham_entity_t *ehdl            = NULL;
    ham_condition_t *chdl_death   = NULL;
    ham_condition_t *chdl_restart = NULL;
    ham_action_t *ahdl            = NULL;

	snprintf(path, PATH_MAX, "/proc/%d/ctl", p_info->pid);
	if (-1 == (fd = open(path, O_RDONLY)))
	{
		printf("open %s failed\n", path);
		return;
	}
	else
	{
		if (EOK != devctl(fd, DCMD_PROC_MAPDEBUG_BASE, &proc, sizeof(proc), 0))
		{
			printf("get bin path failed");
			return;
		}
	}
	snprintf(path, PATH_MAX, "/%s", proc.info.path);

	printf("ham: entity-%s pid-%d path-%s\n", p_info->name, p_info->pid, path);

	ham_connect(0);
	ehdl = ham_attach(p_info->name, 0, p_info->pid, path, 0);
	if (ehdl != NULL)
	{
		chdl_death = ham_condition(ehdl, CONDDEATH, "death", HREARMAFTERRESTART|HCONDINDEPENDENT);
		if (chdl_death != NULL)
		{
			ahdl = ham_action_restart(chdl_death, "restart", path, HREARMAFTERRESTART);
			if (ahdl == NULL)
			{
				printf("ham: %s-add action failed-%s\n", p_info->name, strerror(errno));
			}
		}
		else
		{
			printf("ham: %s-add condition failed-%s\n", p_info->name, strerror(errno));
		}
	}
	else
	{
		printf("ham: %s-add entity failed-%s\n", p_info->name, strerror(errno));
	}
	ham_disconnect(0);
}

int main(int argc, char *argv[])
{
	struct process_info p_info;

	if (argc < 3)
	{
		printf("Usage: ham_service <name> <pid>");
		return -1;
	}

	if (snprintf(p_info.name, NAME_MAX_LEN, "%s", argv[1]) < 0)
	{
		printf("failed to get process name!\n");
		return -1;
	}

	p_info.pid = atoi(argv[2]);

	ham_handle(&p_info);

	return 0;
}