#include <linux/taskstats.h>

#include "netlink/netlink.h"
#include "netlink/genl/genl.h"
#include "netlink/genl/ctrl.h"
#include "netlink/genl/mngt.h"

static struct nla_policy attr_policy[TASKSTATS_TYPE_MAX+1] = {
	[TASKSTATS_TYPE_PID]	= { .type = NLA_U32 },
	[TASKSTATS_TYPE_TGID]	= { .type = NLA_U32 },
	[TASKSTATS_TYPE_STATS]	= { .minlen = sizeof(struct taskstats) },
	[TASKSTATS_TYPE_AGGR_PID] = { .type = NLA_NESTED },
	[TASKSTATS_TYPE_AGGR_TGID] = { .type = NLA_NESTED },
};


static int parse_cmd_new(struct nl_cache_ops *unused, struct genl_cmd *cmd,
			 struct genl_info *info, void *arg)
{
	return 0;
}

static int parse_cb(struct nl_msg *msg, void *arg)
{
	return genl_handle_msg(msg, NULL);
}

static struct genl_cmd cmds[] = {
	{
		.c_id		= TASKSTATS_CMD_NEW,
		.c_name		= "taskstats_new()",
		.c_maxattr	= TASKSTATS_TYPE_MAX,
		.c_attr_policy	= attr_policy,
		.c_msg_parser	= &parse_cmd_new,
	},
};

#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))

static struct genl_ops ops = {
	.o_name = TASKSTATS_GENL_NAME,
	.o_cmds = cmds,
	.o_ncmds = ARRAY_SIZE(cmds),
};

int main(int argc, char *argv[])
{
	struct nl_sock* sock;
	struct nl_msg* msg;
	int err = 0;

	sock = nl_socket_alloc();
	if ( !sock )
	{
		printf( "Failed to allocate socket\n" );
		return -1;
	}
	if ( genl_connect( sock ) < 0 )
	{
		printf( "Failed to connect\n" );
		return -1;
	}

	if ((err = genl_register_family(&ops)) < 0)
	{
		printf( "Unable to register Generic Netlink family\n" );
		return -1;
	}

	if ((err = genl_ops_resolve(sock, &ops)) < 0)
	{
		printf( "Unable to resolve family name\n" );
		return -1;
	}

	if (genl_ctrl_resolve(sock, "nlctrl") != GENL_ID_CTRL)
	{
		printf( "Resolving of \"nlctrl\" failed\n" );
		return -1;
	}

	nl_close(sock);
	nl_socket_free(sock);

	printf( "The end\n" );

	return 0;
}
