// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
#include "util/evlist.h"
#include "evsel.h"
#include "util/evsel_fprintf.h"
#include "util/event.h"
#include "callchain.h"
#include "map.h"
#include "strlist.h"
#include "symbol.h"
#include "srcline.h"
#include "dso.h"

#ifdef HAVE_LIBTRACEEVENT
#include <event-parse.h>
#endif

static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
{
	va_list args;
	int ret = 0;

	if (!*first) {
		ret += fprintf(fp, ",");
	} else {
		ret += fprintf(fp, ":");
		*first = false;
	}

	va_start(args, fmt);
	ret += vfprintf(fp, fmt, args);
	va_end(args);
	return ret;
}

static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
{
	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
}

int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp)
{
	bool first = true;
	int printed = 0;

	if (details->event_group) {
		struct evsel *pos;

		if (!evsel__is_group_leader(evsel))
			return 0;

		if (evsel->core.nr_members > 1)
			printed += fprintf(fp, "%s{", evsel->group_name ?: "");

		printed += fprintf(fp, "%s", evsel__name(evsel));
		for_each_group_member(pos, evsel)
			printed += fprintf(fp, ",%s", evsel__name(pos));

		if (evsel->core.nr_members > 1)
			printed += fprintf(fp, "}");
		goto out;
	}

	printed += fprintf(fp, "%s", evsel__name(evsel));

	if (details->verbose) {
		printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
						    __print_attr__fprintf, &first);
	} else if (details->freq) {
		const char *term = "sample_freq";

		if (!evsel->core.attr.freq)
			term = "sample_period";

		printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
					 term, (u64)evsel->core.attr.sample_freq);
	}

#ifdef HAVE_LIBTRACEEVENT
	if (details->trace_fields) {
		struct tep_format_field *field;
		const struct tep_event *tp_format;

		if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
			printed += comma_fprintf(fp, &first, " (not a tracepoint)");
			goto out;
		}

		tp_format = evsel__tp_format(evsel);
		field = tp_format ? tp_format->format.fields : NULL;
		if (field == NULL) {
			printed += comma_fprintf(fp, &first, " (no trace field)");
			goto out;
		}

		printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);

		field = field->next;
		while (field) {
			printed += comma_fprintf(fp, &first, "%s", field->name);
			field = field->next;
		}
	}
#endif
out:
	fputc('\n', fp);
	return ++printed;
}

int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
			      unsigned int print_opts, struct callchain_cursor *cursor,
			      struct strlist *bt_stop_list, FILE *fp)
{
	int printed = 0;
	struct callchain_cursor_node *node;
	int print_ip = print_opts & EVSEL__PRINT_IP;
	int print_sym = print_opts & EVSEL__PRINT_SYM;
	int print_dso = print_opts & EVSEL__PRINT_DSO;
	int print_dsoff = print_opts & EVSEL__PRINT_DSOFF;
	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
	int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
	int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
	int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
	char s = print_oneline ? ' ' : '\t';
	bool first = true;

	if (cursor == NULL)
		return fprintf(fp, "<not enough memory for the callchain cursor>%s", print_oneline ? "" : "\n");

	if (sample->callchain) {
		callchain_cursor_commit(cursor);

		while (1) {
			struct symbol *sym;
			struct map *map;
			u64 addr = 0;

			node = callchain_cursor_current(cursor);
			if (!node)
				break;

			sym = node->ms.sym;
			map = node->ms.map;

			if (sym && symbol__ignore(sym) && print_skip_ignored)
				goto next;

			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");

			if (print_arrow && !first)
				printed += fprintf(fp, " <-");

			if (map)
				addr = map__map_ip(map, node->ip);

			if (print_ip)
				printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);

			if (print_sym) {
				struct addr_location node_al;

				addr_location__init(&node_al);
				printed += fprintf(fp, " ");
				node_al.addr = addr;
				node_al.map  = map__get(map);

				if (sample->deferred_callchain &&
				    sample->deferred_cookie == node->ip) {
					printed += fprintf(fp, "(cookie)");
				} else if (print_symoffset) {
					printed += __symbol__fprintf_symname_offs(sym, &node_al,
										  print_unknown_as_addr,
										  true, fp);
				} else {
					printed += __symbol__fprintf_symname(sym, &node_al,
									     print_unknown_as_addr, fp);
				}
				addr_location__exit(&node_al);
			}

			if (print_dso && (!sym || !symbol__inlined(sym)))
				printed += map__fprintf_dsoname_dsoff(map, print_dsoff, addr, fp);

			if (print_srcline) {
				if (node->srcline)
					printed += fprintf(fp, "\n  %s", node->srcline);
				else
					printed += map__fprintf_srcline(map, addr, "\n  ", fp);
			}

			if (sym && symbol__inlined(sym))
				printed += fprintf(fp, " (inlined)");

			if (!print_oneline)
				printed += fprintf(fp, "\n");

			/* Add srccode here too? */
			if (bt_stop_list && sym &&
			    strlist__has_entry(bt_stop_list, sym->name)) {
				break;
			}

			first = false;
next:
			callchain_cursor_advance(cursor);
		}
	}

	return printed;
}

int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
			int left_alignment, unsigned int print_opts,
			struct callchain_cursor *cursor, struct strlist *bt_stop_list, FILE *fp)
{
	int printed = 0;
	int print_ip = print_opts & EVSEL__PRINT_IP;
	int print_sym = print_opts & EVSEL__PRINT_SYM;
	int print_dso = print_opts & EVSEL__PRINT_DSO;
	int print_dsoff = print_opts & EVSEL__PRINT_DSOFF;
	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;

	if (cursor != NULL) {
		printed += sample__fprintf_callchain(sample, left_alignment, print_opts,
						     cursor, bt_stop_list, fp);
	} else {
		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");

		if (print_ip)
			printed += fprintf(fp, "%16" PRIx64, sample->ip);

		if (print_sym) {
			printed += fprintf(fp, " ");
			if (print_symoffset) {
				printed += __symbol__fprintf_symname_offs(al->sym, al,
									  print_unknown_as_addr,
									  true, fp);
			} else {
				printed += __symbol__fprintf_symname(al->sym, al,
								     print_unknown_as_addr, fp);
			}
		}

		if (print_dso)
			printed += map__fprintf_dsoname_dsoff(al->map, print_dsoff, al->addr, fp);

		if (print_srcline)
			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
	}

	return printed;
}
