// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com>
 */

// C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// KernelShark
#include "libkshark.h"
#include "libkshark-model.h"

#define N_BINS 5

const char *default_file = "trace.dat";

void dump_bin(struct kshark_trace_histo *histo, int bin, int sd,
	      const char *type, int val)
{
	const struct kshark_entry *e_front, *e_back;
	char *entry_str;
	ssize_t i_front, i_back;

	printf("bin %i {\n", bin);
	if (strcmp(type, "cpu") == 0) {
		e_front = ksmodel_get_entry_front(histo, bin, true,
						  kshark_match_cpu, sd, &val,
						  NULL,
						  &i_front);

		e_back = ksmodel_get_entry_back(histo, bin, true,
						kshark_match_cpu, sd, &val,
						NULL,
						&i_back);
	} else if (strcmp(type, "task") == 0) {
		e_front = ksmodel_get_entry_front(histo, bin, true,
						  kshark_match_pid, sd, &val,
						  NULL,
						  &i_front);

		e_back = ksmodel_get_entry_back(histo, bin, true,
						kshark_match_pid, sd, &val,
						NULL,
						&i_back);
	} else {
		i_front = ksmodel_first_index_at_bin(histo, bin);
		e_front = histo->data[i_front];

		i_back = ksmodel_last_index_at_bin(histo, bin);
		e_back = histo->data[i_back];
	}

	if (i_front == KS_EMPTY_BIN) {
		puts ("EMPTY BIN");
	} else {
		entry_str = kshark_dump_entry(e_front);
		printf("%zd -> %s\n", i_front, entry_str);
		free(entry_str);

		entry_str = kshark_dump_entry(e_back);
		printf("%zd -> %s\n", i_back, entry_str);
		free(entry_str);
	}

	puts("}\n");
}

void dump_histo(struct kshark_trace_histo *histo, int sd, const char *type, int val)
{
	size_t bin;

	for (bin = 0; bin < histo->n_bins; ++bin)
		dump_bin(histo, bin, sd, type, val);
}

int main(int argc, char **argv)
{
	struct kshark_context *kshark_ctx;
	struct kshark_entry **data = NULL;
	struct kshark_trace_histo histo;
	ssize_t i, n_rows, n_tasks;
	int sd, *pids;

	/* Create a new kshark session. */
	kshark_ctx = NULL;
	if (!kshark_instance(&kshark_ctx))
		return 1;

	/* Open a trace data file produced by trace-cmd. */
	if (argc > 1)
		sd = kshark_open(kshark_ctx, argv[1]);
	else
		sd = kshark_open(kshark_ctx, default_file);

	if (sd < 0) {
		kshark_free(kshark_ctx);
		return 1;
	}

	/* Load the content of the file into an array of entries. */
	n_rows = kshark_load_entries(kshark_ctx, sd, &data);
	if (n_rows < 1) {
		kshark_free(kshark_ctx);
		return 1;
	}

	/* Get a list of all tasks. */
	n_tasks = kshark_get_task_pids(kshark_ctx, sd, &pids);

	/* Initialize the Visualization Model. */
	ksmodel_init(&histo);
	ksmodel_set_bining(&histo, N_BINS, data[0]->ts,
					   data[n_rows - 1]->ts);

	/* Fill the model with data and calculate its state. */
	ksmodel_fill(&histo, data, n_rows);

	/* Dump the raw bins. */
	dump_histo(&histo, sd, "", 0);

	puts("\n...\n\n");

	/*
	 * Change the state of the model. Do 50% Zoom-In and dump only CPU 0.
	 */
	ksmodel_zoom_in(&histo, .50, -1);
	dump_histo(&histo, sd, "cpu", 0);

	puts("\n...\n\n");

	/* Shift forward by two bins and this time dump only CPU 1. */
	ksmodel_shift_forward(&histo, 2);
	dump_histo(&histo, sd, "cpu", 1);

	puts("\n...\n\n");

	/*
	 * Do 10% Zoom-Out, using the last bin as a focal point. Dump the last
	 * Task.
	 */
	ksmodel_zoom_out(&histo, .10, N_BINS - 1);
	dump_histo(&histo, sd, "task", pids[n_tasks - 1]);

	/* Reset (clear) the model. */
	ksmodel_clear(&histo);

	/* Free the memory. */
	for (i = 0; i < n_rows; ++i)
		free(data[i]);

	free(data);

	/* Close the file. */
	kshark_close(kshark_ctx, sd);

	/* Close the session. */
	kshark_free(kshark_ctx);

	return 0;
}
