// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/time.h>
#include <sys/types.h>

#include "trace-local.h"

/*
 * Stream runs for a single machine. We are going to cheat
 * and use the trace-output and trace-input code to create
 * our pevent. First just create a trace.dat file and then read
 * it to create the pevent and handle.
 */
struct tracecmd_input *
trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
		  struct hook_list *hooks,
		  tracecmd_handle_init_func handle_init, int global)
{
	struct tracecmd_input *trace_input;
	struct tracecmd_output *trace_output;
	static FILE *fp = NULL;
	static int tfd;
	static int ofd;
	long flags;

	if (instance->handle) {
		trace_input = instance->handle;
		goto make_pipe;
	}

	if (!fp) {
		fp = tmpfile();
		if (!fp)
			return NULL;
		tfd = fileno(fp);

		ofd = dup(tfd);
		trace_output = tracecmd_create_init_fd(ofd);
		if (!trace_output) {
			fclose(fp);
			return NULL;
		}
		tracecmd_output_free(trace_output);
	}

	lseek(ofd, 0, SEEK_SET);

	trace_input = tracecmd_alloc_fd(ofd);
	if (!trace_input) {
		close(ofd);
		goto fail;
	}

	if (tracecmd_read_headers(trace_input) < 0)
		goto fail_free_input;

	if (handle_init)
		handle_init(trace_input, hooks, global);

 make_pipe:
	/* Do not block on this pipe */
	flags = fcntl(fd, F_GETFL);
	fcntl(fd, F_SETFL, flags | O_NONBLOCK);

	if (tracecmd_make_pipe(trace_input, cpu, fd, cpus) < 0)
		goto fail_free_input;

	instance->handle = trace_input;

	return trace_input;

 fail_free_input:
	tracecmd_close(trace_input);
 fail:
	fclose(fp);

	return NULL;
}

int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv)
{
	struct tep_record *record;
	struct pid_record_data *pid;
	struct pid_record_data *last_pid;
	fd_set rfds;
	int top_rfd = 0;
	int nr_fd;
	int ret;
	int i;

	last_pid = NULL;

 again:
	for (i = 0; i < nr_pids; i++) {
		pid = &pids[i];

		if (!pid->record)
			pid->record = tracecmd_read_data(pid->instance->handle, pid->cpu);
		record = pid->record;
		if (!record && errno == EINVAL)
			/* pipe has closed */
			pid->closed = 1;

		if (record &&
		    (!last_pid || record->ts < last_pid->record->ts))
			last_pid = pid;
	}
	if (last_pid) {
		trace_show_data(last_pid->instance->handle, last_pid->record);
		free_record(last_pid->record);
		last_pid->record = NULL;
		return 1;
	}

	nr_fd = 0;
	FD_ZERO(&rfds);

	for (i = 0; i < nr_pids; i++) {
		/* Do not process closed pipes */
		if (pids[i].closed)
			continue;
		nr_fd++;
		if (pids[i].brass[0] > top_rfd)
			top_rfd = pids[i].brass[0];

		FD_SET(pids[i].brass[0], &rfds);
	}

	if (!nr_fd)
		return 0;

	ret = select(top_rfd + 1, &rfds, NULL, NULL, tv);

	if (ret > 0)
		goto again;

	return ret;
}
