/*
 * Powerdebug : power debugging tool
 *
 * Copyright (C) 2016, Linaro Limited.
 *
 * Author:
 * Daniel Lezcano <daniel.lezcano@linaro.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#define SYSFS_REGULATOR "/sys/class/regulator"
#define VALUE_MAX 16

#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <sys/types.h>
#include <stdbool.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include "display.h"
#include "powerdebug.h"
#include "tree.h"
#include "utils.h"

struct regulator_info {
	char name[NAME_MAX];
	char state[VALUE_MAX];
	char status[VALUE_MAX];
	char type[VALUE_MAX];
	char opmode[VALUE_MAX];
	int microvolts;
	int min_microvolts;
	int max_microvolts;
	int microamps;
	int min_microamps;
	int max_microamps;
	int requested_microamps;
	int num_users;
};

struct regulator_data {
	const char *name;
	const char *ifmt;
	const char *ofmt;
	bool derefme;
};

static struct regulator_data regdata[] = {
	{ "name",           "%s", "\tname: %s\n"                 },
	{ "status",         "%s", "\tstatus: %s\n"               },
	{ "state",          "%s", "\tstate: %s\n"                },
	{ "type",           "%s", "\ttype: %s\n"                 },
	{ "num_users",      "%d", "\tnum_users: %d\n",      true },
	{ "microvolts",     "%d", "\tmicrovolts: %d\n",     true },
	{ "max_microvolts", "%d", "\tmax_microvolts: %d\n", true },
	{ "min_microvolts", "%d", "\tmin_microvolts: %d\n", true },
};

static struct tree *reg_tree;
static bool regulator_error = false;

static struct regulator_info *regulator_alloc(void)
{
	struct regulator_info *regi;

	regi = malloc(sizeof(*regi));
	if (regi)
		memset(regi, 0, sizeof(*regi));

	return regi;
}

static int regulator_dump_cb(struct tree *tree, void *data)
{
	int i;
	char buffer[NAME_MAX];
	size_t nregdata = sizeof(regdata) / sizeof(regdata[0]);

	if (!strncmp("regulator.", tree->name, strlen("regulator.")))
		printf("\n%s:\n", tree->name);

	for (i = 0; i < nregdata; i++) {
		int val;

		if (file_read_value(tree->path, regdata[i].name,
				    regdata[i].ifmt, buffer))
			continue;

		if (regdata[i].derefme) {
			val = atoi(buffer);
			printf(regdata[i].ofmt, val);
		} else
			printf(regdata[i].ofmt, buffer);
	}

	return 0;
}

int regulator_dump(void)
{
	printf("\nRegulator Information:\n");
	printf("*********************\n\n");

	return tree_for_each(reg_tree, regulator_dump_cb, NULL);
}

static int regulator_display_cb(struct tree *t, void *data)
{
	struct regulator_info *reg = t->private;
	int *line = data;
	char *buf;

        /* we skip the root node of the tree */
	if (!t->parent)
		return 0;

	if (!strlen(reg->name))
		return 0;

	if (asprintf(&buf, "%-11s %-11s %-11s %-11s %-11d %-11d %-11d %-12d",
		     reg->name, reg->status, reg->state, reg->type,
		     reg->num_users, reg->microvolts, reg->min_microvolts,
		     reg->max_microvolts) < 0)
		return -1;

	display_print_line(REGULATOR, *line, buf, reg->num_users, t);

	(*line)++;

	free(buf);

	return 0;
}

static int regulator_print_header(void)
{
	char *buf;
	int ret;

	if (asprintf(&buf, "%-11s %-11s %-11s %-11s %-11s %-11s %-11s %-12s",
		     "Name", "Status", "State", "Type", "Users", "Microvolts",
		     "Min u-volts", "Max u-volts") < 0)
		return -1;

	ret = display_column_name(buf);

	free(buf);

	return ret;

}

static int regulator_filter_cb(const char *name)
{
	/* let's ignore some directories in order to avoid to be
	 * pulled inside the sysfs circular symlinks mess/hell
	 * (choose the word which fit better)
	 */
	if (!strcmp(name, "device"))
		return 1;

	if (!strcmp(name, "subsystem"))
		return 1;

	if (!strcmp(name, "driver"))
		return 1;

	return 0;
}

static inline int read_regulator_cb(struct tree *t, void *data)
{
	struct regulator_info *reg = t->private;

	file_read_value(t->path, "name", "%s", reg->name);
	file_read_value(t->path, "state", "%s", reg->state);
	file_read_value(t->path, "status", "%s", reg->status);
	file_read_value(t->path, "type", "%s", reg->type);
	file_read_value(t->path, "opmode", "%s", reg->opmode);
	file_read_value(t->path, "num_users", "%d", &reg->num_users);
	file_read_value(t->path, "microvolts", "%d", &reg->microvolts);
	file_read_value(t->path, "min_microvolts", "%d", &reg->min_microvolts);
	file_read_value(t->path, "max_microvolts", "%d", &reg->max_microvolts);
	file_read_value(t->path, "microamps", "%d", &reg->microamps);
	file_read_value(t->path, "min_microamps", "%d", &reg->min_microamps);
	file_read_value(t->path, "max_microamps", "%d", &reg->max_microamps);

	return 0;
}

static int read_regulator_info(struct tree *tree)
{
	return tree_for_each(tree, read_regulator_cb, NULL);
}

static int regulator_print_info(struct tree *tree)
{
	int ret, line = 0;

	display_reset_cursor(REGULATOR);

	regulator_print_header();

	ret = tree_for_each(tree, regulator_display_cb, &line);

	display_refresh_pad(REGULATOR);

	return ret;
}

static int regulator_display(bool refresh)
{
	if (regulator_error) {
		display_message(REGULATOR,
			"error: path " SYSFS_REGULATOR " not found");
		return -2;
	}

	if (refresh && read_regulator_info(reg_tree))
		return -1;

	return regulator_print_info(reg_tree);
}

static int fill_regulator_cb(struct tree *t, void *data)
{
	struct regulator_info *reg;

	reg = regulator_alloc();
	if (!reg) {
		printf("error: unable to allocate memory for regulator\n");
		return -1;
	}
	t->private = reg;

        /* we skip the root node but we set it expanded for its children */
	if (!t->parent)
		return 0;

	return read_regulator_cb(t, data);
}

static int fill_regulator_tree(void)
{
	return tree_for_each(reg_tree, fill_regulator_cb, NULL);
}

static struct display_ops regulator_ops = {
	.display = regulator_display,
};

int regulator_init(struct powerdebug_options *options)
{
	int ret = 0;

	if (!(options->flags & REGULATOR_OPTION))
		return 0;

	ret = display_register(REGULATOR, &regulator_ops);
	if (ret)
		printf("error: regulator display register failed");

	if (access(SYSFS_REGULATOR, F_OK))
		regulator_error = true; /* set the flag */

	reg_tree = tree_load(SYSFS_REGULATOR, regulator_filter_cb, false);
	if (!reg_tree)
		return -1;

	if (fill_regulator_tree())
		return -1;

	return ret;
}
