/*
 * Power debug tool (powerdebug)
 *
 * Copyright (C) 2016, Linaro Limited.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <getopt.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ncurses.h>
#include "display.h"
#include "mainloop.h"
#include "powerdebug.h"

void usage(void)
{
	printf("Usage: powerdebug [OPTIONS]\n");
	printf("\n");
	printf("powerdebug -d [ -r ] [ -s ] [ -c [ -f <clock-name> ] ] "
		"[ -g ] [ -p ] [ -v ]\n");
	printf("powerdebug [ -r | -s | -c | -g | -p]\n");
	printf("  -r, --regulator 	Show regulator information\n");
	printf("  -s, --sensor		Show sensor information\n");
	printf("  -c, --clock		Show clock information\n");
	printf("  -f, --findparents	Show all parents for a particular"
		" clock\n");
	printf("  -g, --gpio		Show gpio information\n");
	printf("  -p, --powerdomain	Show powerdomain information\n");
	printf("  -t, --time		Set ticktime in seconds (eg. 10.0)\n");
	printf("  -d, --dump		Dump information once (no refresh)\n");
	printf("  -v, --verbose		Verbose mode (use with -r and/or"
		" -s)\n");
	printf("  -V, --version		Show Version\n");
	printf("  -h, --help 		Help\n");
}

void version()
{
	printf("powerdebug version %s\n", VERSION);
}

/*
 * Options:
 * -r, --regulator      : regulators
 * -s, --sensor	 	: sensors
 * -c, --clock	  	: clocks
 * -g, --gpio           : gpios
 * -p, --powerdomain	: powerdomains
 * -f, --findparents    : clockname whose parents have to be found
 * -t, --time		: ticktime
 * -d, --dump		: dump
 * -v, --verbose	: verbose
 * -V, --version	: version
 * -h, --help		: help
 * no option / default : show usage!
 */

static struct option long_options[] = {
	{ "regulator", 0, 0, 'r' },
	{ "sensor", 0, 0, 's' },
	{ "clock",  0, 0, 'c' },
	{ "gpio",  0, 0, 'g' },
	{ "powerdomain", 0, 0, 'p' },
	{ "findparents", 1, 0, 'f' },
	{ "time", 1, 0, 't' },
	{ "dump", 0, 0, 'd' },
	{ "verbose", 0, 0, 'v' },
	{ "version", 0, 0, 'V' },
	{ "help", 0, 0, 'h' },
	{ 0, 0, 0, 0 }
};

int getoptions(int argc, char *argv[], struct powerdebug_options *options)
{
	int c;

	memset(options, 0, sizeof(*options));
	options->ticktime = 1;

	while (1) {
		int optindex = 0;

		c = getopt_long(argc, argv, "rscgpf:t:dvVh",
				long_options, &optindex);
		if (c == -1)
			break;

		switch (c) {
		case 'r':
			options->flags |= REGULATOR_OPTION;
			break;
		case 's':
			options->flags |= SENSOR_OPTION;
			break;
		case 'c':
			options->flags |= CLOCK_OPTION;
			break;
		case 'g':
			options->flags |= GPIO_OPTION;
			break;
		case 'p':
			options->flags |= GENPD_OPTION;
			break;
		case 'd':
			options->flags |= DUMP_OPTION;
			break;
		case 'v':
			options->flags |= VERBOSE_OPTION;
			break;
		case 'f':
			options->clkname = strdup(optarg);
			if (!options->clkname) {
				fprintf(stderr, "failed to allocate memory");
				return -1;
			}
			options->flags |= (DUMP_OPTION | CLOCK_OPTION);
			break;
		case 't':
			options->ticktime = atoi(optarg);
			break;
		case 'V':
			version();
			break;
		case '?':
			fprintf(stderr, "%s: Unknown option %c'.\n",
				argv[0], optopt);
		default:
			return -1;
		}
	}

	/* No system specified to be dump, let's default to all */
	if (!(options->flags & DEFAULT_OPTION))
		options->flags |= DEFAULT_OPTION;

	return 0;
}

static int powerdebug_dump(struct powerdebug_options *options)
{
	if (options->flags & REGULATOR_OPTION)
		regulator_dump();

	if (options->flags & CLOCK_OPTION)
		clock_dump(options->clkname);

	if (options->flags & SENSOR_OPTION)
		sensor_dump();

	if (options->flags & GPIO_OPTION)
		gpio_dump();

	if (options->flags & GENPD_OPTION)
		genpd_dump();

	return 0;
}

static int powerdebug_display(struct powerdebug_options *options)
{
	if (display_init(options)) {
		printf("failed to initialize display\n");
		return -1;
	}

	if (mainloop(options->ticktime * 1000))
		return -1;

	return 0;
}

static struct powerdebug_options *powerdebug_init(void)
{
	struct powerdebug_options *options;

	options = malloc(sizeof(*options));
	if (!options)
		return NULL;

	return options;
}

int main(int argc, char **argv)
{
	struct powerdebug_options *options;
	int ret;

#ifdef __ANDROID__
	if (setenv("TERM", "xterm", 1) < 0) {
		fprintf(stderr, "setenv failure");
		return 1;
	}
	if (setenv("TERMINFO", "/system/etc/terminfo", 1) < 0) {
		fprintf(stderr, "setenv failure");
		return 1;
	}
#endif
	options = powerdebug_init();
	if (!options) {
		fprintf(stderr, "not enough memory to allocate options\n");
		return 1;
	}

	if (getoptions(argc, argv, options)) {
		usage();
		return 1;
	}

	if (mainloop_init()) {
		fprintf(stderr, "failed to initialize the mainloop\n");
		return 1;
	}

	if (regulator_init(options)) {
		printf("failed to initialize regulator\n");
		options->flags &= ~REGULATOR_OPTION;
	}

	if (clock_init(options)) {
		printf("failed to initialize clock details (check debugfs)\n");
		options->flags &= ~CLOCK_OPTION;
	}

	if (sensor_init(options)) {
		printf("failed to initialize sensors\n");
		options->flags &= SENSOR_OPTION;
	}

	if (gpio_init(options)) {
		printf("failed to initialize gpios\n");
		options->flags &= GPIO_OPTION;
	}

	if (genpd_init(options)) {
		printf("failed to initialize genpd details\n");
		options->flags &= GENPD_OPTION;
	}

	ret = options->flags & DUMP_OPTION ? powerdebug_dump(options) :
		powerdebug_display(options);

	return ret < 0;
}
