#include "util.h"
#include "../perf.h"
#include "parse-options.h"
#include "evsel.h"
#include "cgroup.h"
#include "evlist.h"

int nr_cgroups;

static int
cgroupfs_find_mountpoint(char *buf, size_t maxlen)
{
	FILE *fp;
	char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
	char *token, *saved_ptr = NULL;
	int found = 0;

	fp = fopen("/proc/mounts", "r");
	if (!fp)
		return -1;

	/*
	 * in order to handle split hierarchy, we need to scan /proc/mounts
	 * and inspect every cgroupfs mount point to find one that has
	 * perf_event subsystem
	 */
	while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %"
				STR(PATH_MAX)"s %*d %*d\n",
				mountpoint, type, tokens) == 3) {

		if (!strcmp(type, "cgroup")) {

			token = strtok_r(tokens, ",", &saved_ptr);

			while (token != NULL) {
				if (!strcmp(token, "perf_event")) {
					found = 1;
					break;
				}
				token = strtok_r(NULL, ",", &saved_ptr);
			}
		}
		if (found)
			break;
	}
	fclose(fp);
	if (!found)
		return -1;

	if (strlen(mountpoint) < maxlen) {
		strcpy(buf, mountpoint);
		return 0;
	}
	return -1;
}

static int open_cgroup(char *name)
{
	char path[PATH_MAX + 1];
	char mnt[PATH_MAX + 1];
	int fd;


	if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1))
		return -1;

	snprintf(path, PATH_MAX, "%s/%s", mnt, name);

	fd = open(path, O_RDONLY);
	if (fd == -1)
		fprintf(stderr, "no access to cgroup %s\n", path);

	return fd;
}

static int add_cgroup(struct perf_evlist *evlist, char *str)
{
	struct perf_evsel *counter;
	struct cgroup_sel *cgrp = NULL;
	int n;
	/*
	 * check if cgrp is already defined, if so we reuse it
	 */
	evlist__for_each(evlist, counter) {
		cgrp = counter->cgrp;
		if (!cgrp)
			continue;
		if (!strcmp(cgrp->name, str))
			break;

		cgrp = NULL;
	}

	if (!cgrp) {
		cgrp = zalloc(sizeof(*cgrp));
		if (!cgrp)
			return -1;

		cgrp->name = str;

		cgrp->fd = open_cgroup(str);
		if (cgrp->fd == -1) {
			free(cgrp);
			return -1;
		}
	}

	/*
	 * find corresponding event
	 * if add cgroup N, then need to find event N
	 */
	n = 0;
	evlist__for_each(evlist, counter) {
		if (n == nr_cgroups)
			goto found;
		n++;
	}
	if (atomic_read(&cgrp->refcnt) == 0)
		free(cgrp);

	return -1;
found:
	atomic_inc(&cgrp->refcnt);
	counter->cgrp = cgrp;
	return 0;
}

void close_cgroup(struct cgroup_sel *cgrp)
{
	if (cgrp && atomic_dec_and_test(&cgrp->refcnt)) {
		close(cgrp->fd);
		zfree(&cgrp->name);
		free(cgrp);
	}
}

int parse_cgroups(const struct option *opt __maybe_unused, const char *str,
		  int unset __maybe_unused)
{
	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
	const char *p, *e, *eos = str + strlen(str);
	char *s;
	int ret;

	if (list_empty(&evlist->entries)) {
		fprintf(stderr, "must define events before cgroups\n");
		return -1;
	}

	for (;;) {
		p = strchr(str, ',');
		e = p ? p : eos;

		/* allow empty cgroups, i.e., skip */
		if (e - str) {
			/* termination added */
			s = strndup(str, e - str);
			if (!s)
				return -1;
			ret = add_cgroup(evlist, s);
			if (ret) {
				free(s);
				return -1;
			}
		}
		/* nr_cgroups is increased een for empty cgroups */
		nr_cgroups++;
		if (!p)
			break;
		str = p+1;
	}
	return 0;
}
