/*******************************************************************************
 * Copyright (C) 2010, Linaro Limited.
 *
 * This file is part of PowerDebug.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Amit Arora <amit.arora@linaro.org> (IBM Corporation)
 *       - initial API and implementation
 *******************************************************************************/

#include "powerdebug.h"
#include "clocks.h"

static char clk_dir_path[PATH_MAX];
static char clk_name[NAME_MAX];
static int  bold[MAX_LINES];

int init_clock_details(bool dump, int selectedwindow)
{
	char *path = debugfs_locate_mpoint();
	struct stat buf;

	if (path)
		strcpy(clk_dir_path, path);
	else {
		if (!dump) {
			create_selectedwindow(selectedwindow);
			sprintf(clock_lines[0], "Unable to locate debugfs "
				"mount point. Mount debugfs "
				"and try again..\n");
			print_one_clock(0, clock_lines[0], 1, 0);
			old_clock_line_no = 1;
			return(1);
		} else {
			fprintf(stderr, "powerdebug: Unable to locate debugfs "
				"mount point. Mount debugfs and try "
				"again..\n");
			exit(1);
		}
	}
	sprintf(clk_dir_path, "%s/clock", clk_dir_path);
	//strcpy(clk_dir_path, "/debug/clock"); // Hardcoded for testing..
	if (stat(clk_dir_path, &buf)) {
		if (!dump) {
			create_selectedwindow(selectedwindow);
			sprintf(clock_lines[0], "Unable to find clock tree"
				" information at %s.\n", clk_dir_path);
			print_one_clock(0, clock_lines[0], 1, 0);
			old_clock_line_no = 1;
			return(1);
		} else {
			fprintf(stderr, "powerdebug: Unable to find clock tree"
				" information at %s.\n", clk_dir_path);
			exit(1);
		}
	}
	strcpy(clk_name, "");
	return(0);
}

int get_int_from(char *file)
{
	FILE *filep;
	char result[NAME_MAX];
	int ret;

	filep = fopen(file, "r");

	if (!filep)
		return -1;  //TBD : What should we return on failure, here ?

	ret = fscanf(filep, "%s", result);
	fclose(filep);

	return atoi(result);
}

static void dump_parent(struct clock_info *clk, int line, bool dump)
{
	char *unit = "Hz";
	double drate;
	static char spaces[64];
	char str[256];
	static int maxline;

	if (maxline < line)
		maxline = line;

	if (clk && clk->parent)
		dump_parent(clk->parent, ++line, dump);

	drate = (double)clk->rate;
	if (drate > 1000 && drate < 1000000) {
		unit = "KHz";
		drate /= 1000;
	}
	if (drate > 1000000) {
		unit = "MHz";
		drate /= 1000000;
	}
	if (clk == clocks_info) {
		line++;
		strcpy(spaces, "");
		sprintf(str, "%s%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
			spaces, clk->name, clk->flags, clk->usecount, drate,
			unit);
	} else {
		if (!(clk->parent == clocks_info))
			strcat(spaces, "  ");
		sprintf(str, "%s`- %s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
			spaces, clk->name, clk->flags, clk->usecount, drate,
			unit);
	}
	if (dump)
		//printf("line=%d:m%d:l%d %s", maxline - line + 2, maxline, line, str);
		printf("%s", str);
	else
		print_one_clock(maxline - line + 2, str, 1, 0);
}

static void dump_all_parents(char *clkarg, bool dump)
{
	struct clock_info *clk;
	char spaces[1024];

	strcpy(spaces, "");

	clk = find_clock(clocks_info, clkarg);

	if (!clk)
		printf("Clock NOT found!\n");
	else {
		/* while(clk && clk != clocks_info) { */
		/* 	printf("%s\n", clk->name); */
		/* 	strcat(spaces, "  "); */
		/* 	clk = clk->parent; */
		/* 	printf("%s <-- ", spaces); */
		/* } */
		/* printf("  /\n"); */
		dump_parent(clk, 1, dump);
	}
}

void find_parents_for_clock(char *clkname, int complete, bool dump)
{
	char name[256];

	name[0] = '\0';
	if (!complete) {
		char str[256];

		strcat(name, clkname);
		sprintf(str, "Enter Clock Name : %s\n", name);
		print_one_clock(2, str, 1, 0);
		return;
	}
	sprintf(name, "Parents for \"%s\" Clock : \n", clkname);
	print_one_clock(0, name, 1, 1);
	dump_all_parents(clkname, dump);
}

int read_and_print_clock_info(int verbose, int hrow, int selected)
{
	print_one_clock(0, "Reading Clock Tree ...", 1, 1);

	if (!old_clock_line_no || selected == REFRESH_WINDOW) {
		destroy_clocks_info();
		read_clock_info(clk_dir_path);
	}

	if (!clocks_info->num_children) {
		fprintf(stderr, "powerdebug: No clocks found. Exiting..\n");
		exit(1);
	}

	if (selected == CLOCK_SELECTED)
		selected = 1;
	else
		selected = 0;

	print_clock_info(verbose, hrow, selected);
	hrow = (hrow < old_clock_line_no) ? hrow : old_clock_line_no - 1;

	return hrow;
}

int calc_delta_screen_size(int hrow)
{
	if (hrow >= (maxy - 3))
		return hrow - (maxy - 4);

	return 0;
}

void print_clock_info(int verbose, int hrow, int selected)
{
	int i, count = 0, delta;

	(void)verbose;

	print_clock_header();

	for (i = 0; i < clocks_info->num_children; i++)
		add_clock_details_recur(clocks_info->children[i],
					hrow, selected);

	delta = calc_delta_screen_size(hrow);

	while (clock_lines[count + delta] &&
		strcmp(clock_lines[count + delta], "")) {
		if (count < delta) {
			count++;
			continue;
		}
		print_one_clock(count - delta, clock_lines[count + delta],
				bold[count + delta], (hrow == (count + delta)));
		count++;
	}

	old_clock_line_no = clock_line_no;
	clock_line_no = 0;
}

void prepare_name_str(char *namestr, struct clock_info *clock)
{
	int i;

	strcpy(namestr, "");
	if (clock->level > 1)
		for (i = 0; i < (clock->level - 1); i++)
			strcat(namestr, "  ");
	strcat(namestr, clock->name);
}

void add_clock_details_recur(struct clock_info *clock, int hrow, int selected)
{
	int i;
	char *unit = " Hz";
	char rate_str[64];
	char name_str[256];
	double drate = (double)clock->rate;

	if (drate > 1000 && drate < 1000000) {
		unit = "KHz";
		drate /= 1000;
	}
	if (drate > 1000000) {
		unit = "MHz";
		drate /= 1000000;
	}
	if (clock->usecount)
		bold[clock_line_no] = 1;
	else
		bold[clock_line_no] = 0;

	sprintf(rate_str, "%.2f %s", drate, unit);
	prepare_name_str(name_str, clock);
	sprintf(clock_lines[clock_line_no++], "%-55s %-4d  %-12s %-12d %-12d",
		name_str, clock->flags, rate_str, clock->usecount,
		clock->num_children);

	if (selected && (hrow == (clock_line_no - 1))) {
		if (clock->expanded)
			collapse_all_subclocks(clock);
		else
			clock->expanded = 1;
		selected = 0;
	}

	if (clock->expanded && clock->num_children)
		for (i = 0; i < clock->num_children; i++)
			add_clock_details_recur(clock->children[i],
						hrow, selected);
	strcpy(clock_lines[clock_line_no], "");
}

void collapse_all_subclocks(struct clock_info *clock)
{
	int i;

	clock->expanded = 0;
	if (clock->num_children)
		for (i = 0; i < clock->num_children; i++)
			collapse_all_subclocks(clock->children[i]);
}

void destroy_clocks_info(void)
{
	int i;

	if (!clocks_info)
		return;

	if (clocks_info->num_children) {
		for (i = (clocks_info->num_children - 1); i >= 0 ; i--) {
			destroy_clocks_info_recur(clocks_info->children[i]);
			if (!i) {
				free(clocks_info->children);
				clocks_info->children = NULL;
			}
		}
	}
	clocks_info->num_children = 0;
	free(clocks_info);
	clocks_info = NULL;
}

void destroy_clocks_info_recur(struct clock_info *clock)
{
	int i;

	if (clock && clock->num_children) {
		for (i = (clock->num_children - 1); i >= 0; i--) {
			fflush(stdin);
			destroy_clocks_info_recur(clock->children[i]);
			if (!i) {
				free(clock->children);
				clock->children = NULL;
				clock->num_children = 0;
			}
		}
	}
}

void read_and_dump_clock_info_one(char *clk, bool dump)
{
	printf("\nParents for \"%s\" Clock :\n\n", clk);
	read_clock_info(clk_dir_path);
	dump_all_parents(clk, dump);
	printf("\n\n");
}

void read_and_dump_clock_info(int verbose)
{
	(void)verbose;
	printf("\nClock Tree :\n");
	printf("**********\n");
	read_clock_info(clk_dir_path);
	dump_clock_info(clocks_info, 1, 1);
	printf("\n\n");
}

void read_clock_info(char *clkpath)
{
	DIR *dir;
	struct dirent *item;
	char filename[NAME_MAX], clockname[NAME_MAX];
	struct clock_info *child;
	struct clock_info *cur;

	dir = opendir(clkpath);
	if (!dir)
		return;

	clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info));
	memset(clocks_info, 0, sizeof(clocks_info));
	strcpy(clocks_info->name, "/");
	clocks_info->level = 0;

	while ((item = readdir(dir))) {
		/* skip hidden dirs except ".." */
		if (item->d_name[0] == '.')
			continue;

		strcpy(clockname, item->d_name);
		sprintf(filename, "%s/%s", clkpath, item->d_name);
		cur = (struct clock_info *)malloc(sizeof(struct clock_info));
		memset(cur, 0, sizeof(struct clock_info));
		strcpy(cur->name, clockname);
		cur->parent = clocks_info;
		cur->num_children = 0;
		cur->expanded = 0;
		cur->level = 1;
		insert_children(&clocks_info, cur);
		child = read_clock_info_recur(filename, 2, cur);
	}
	closedir(dir);
}

struct clock_info *read_clock_info_recur(char *clkpath, int level,
					struct clock_info *parent)
{
	int ret = 0;
	DIR *dir;
	char filename[PATH_MAX];
	struct dirent *item;
	struct clock_info *cur = NULL;
	struct stat buf;

	dir = opendir(clkpath);
	if (!dir)
		return NULL;

	while ((item = readdir(dir))) {
		struct clock_info *child;
		/* skip hidden dirs except ".." */
		if (item->d_name[0] == '.' )
			continue;

		sprintf(filename, "%s/%s", clkpath, item->d_name);

		ret = stat(filename, &buf);

		if (ret < 0) {
			printf("Error doing a stat on %s\n", filename);
			exit(1);
		}

		if (S_ISREG(buf.st_mode)) {
			if (!strcmp(item->d_name, "flags"))
				parent->flags = get_int_from(filename);
			if (!strcmp(item->d_name, "rate"))
				parent->rate = get_int_from(filename);
			if (!strcmp(item->d_name, "usecount"))
				parent->usecount = get_int_from(filename);
			continue;
		}

		if (!S_ISDIR(buf.st_mode))
			continue;

		cur = (struct clock_info *)malloc(sizeof(struct clock_info));
		memset(cur, 0, sizeof(cur));
		strcpy(cur->name, item->d_name);
		cur->children = NULL;
		cur->parent = NULL;
		cur->num_children = 0;
		cur->expanded = 0;
		cur->level = level;
		child = read_clock_info_recur(filename, level + 1, cur);
		insert_children(&parent, cur);
		cur->parent = parent;
	}
	closedir(dir);

	return cur;
}

void insert_children(struct clock_info **parent, struct clock_info *clk)
{
	if (!(*parent)->num_children || (*parent)->children == NULL) {
		(*parent)->children = (struct clock_info **)
			malloc(sizeof(struct clock_info *)*2);
		(*parent)->num_children = 0;
	} else
		(*parent)->children = (struct clock_info **)
			realloc((*parent)->children,
				sizeof(struct clock_info *) *
				((*parent)->num_children + 2));
	if ((*parent)->num_children > 0)
		(*parent)->children[(*parent)->num_children - 1]->last_child
			= 0;
	clk->last_child = 1;
	(*parent)->children[(*parent)->num_children] = clk;
	(*parent)->children[(*parent)->num_children + 1] = NULL;
	(*parent)->num_children++;
}

struct clock_info *find_clock(struct clock_info *clk, char *clkarg)
{
	int i;
	struct clock_info *ret = clk;

	if (!strcmp(clk->name, clkarg))
		return ret;

	if (clk->children) {
		for (i = 0; i < clk->num_children; i++) {
			if (!strcmp(clk->children[i]->name, clkarg))
				return clk->children[i];
		}
		for (i = 0; i < clk->num_children; i++) {
			ret = find_clock(clk->children[i], clkarg);
			if (ret)
				return ret;
		}
	}

	return NULL;
}


void dump_clock_info(struct clock_info *clk, int level, int bmp)
{
	int i, j;

	if (!clk)
		return;

	for (i = 1, j = 0; i < level; i++, j = (i - 1)) {
		if (i == (level - 1)) {
			if (clk->last_child)
				printf("`-- ");
			else
				printf("|-- ");
		} else {
			if ((1<<j) & bmp)
				printf("|   ");
			else
				printf("    ");
		}
	}

	if (clk == clocks_info)
		printf("%s\n", clk->name);
	else {
		char *unit = "Hz";
		double drate = (double)clk->rate;

		if (drate > 1000 && drate < 1000000) {
			unit = "KHz";
			drate /= 1000;
		}
		if (drate > 1000000) {
			unit = "MHz";
			drate /= 1000000;
		}
		printf("%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
			clk->name, clk->flags, clk->usecount, drate, unit);
	}
	if (clk->children) {
		int tbmp = bmp;
		int xbmp = -1;

		if (clk->last_child) {
			xbmp ^= 1 << (level - 2);

			xbmp = tbmp & xbmp;
		} else
			xbmp = bmp;
		for (i = 0; i < clk->num_children; i++) {
			tbmp = xbmp | (1 << level);
			dump_clock_info(clk->children[i], level + 1, tbmp);
		}
	}
}

char *debugfs_locate_mpoint(void)
{
	int ret;
	FILE *filep;
	char **path;
	char fsname[64];
	struct statfs sfs;

	path = likely_mpoints;
	while (*path) {
		ret = statfs(*path, &sfs);
		if (ret >= 0 && sfs.f_type == (long)DEBUGFS_MAGIC)
			return *path;
		path++;
	}

	filep = fopen("/proc/mounts", "r");
	if (filep == NULL) {
		fprintf(stderr, "powerdebug: Error opening /proc/mounts.");
		exit(1);
	}

	while (fscanf(filep, "%*s %s %s %*s %*d %*d\n",
			debugfs_mntpoint, fsname) == 2)
		if (!strcmp(fsname, "debugfs"))
			break;
	fclose(filep);

	if (strcmp(fsname, "debugfs"))
		return NULL;

	return debugfs_mntpoint;
}
