/*
 * Copyright 2020 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/shell/shell.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>

/**
 * @brief Collect the values for several channels
 *
 * @param dev Sensor device to read from
 * @param ... any number of pairs of arguments:
 *	first is the sensor channel to read (-1 to terminate the list)
 *	second is a pointer to the struct sensor_value to put it in
 * @return 0 on success
 * @return negative error code from sensor API on failure
 */
static int get_channels(const struct device *dev, ...)
{
	va_list ptr;
	int i;

	va_start(ptr, dev);
	for (i = 0;; i++) {
		int chan;
		struct sensor_value *val;
		int err;

		chan = va_arg(ptr, int);
		if (chan == -1) {
			break;
		}
		val = va_arg(ptr, struct sensor_value *);
		err = sensor_channel_get(dev, chan, val);
		if (err < 0) {
			va_end(ptr);
			return err;
		}
	}

	va_end(ptr);
	return 0;
}

/* battery */
static int cmd_battery(const struct shell *shell, size_t argc, char **argv)
{
	struct sensor_value temp, volt, current, i_desired, charge_remain;
	struct sensor_value charge, v_desired, v_design, cap, nom_cap;
	struct sensor_value full, empty;
	const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(battery));
	bool allowed;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(shell, "Device not ready (%s)", argv[1]);
		return -ENODEV;
	}

	err = sensor_sample_fetch(dev);
	if (err < 0) {
		shell_error(shell, "Failed to read sensor: %d", err);
	}

	err = get_channels(dev,
			   SENSOR_CHAN_GAUGE_TEMP, &temp,
			   SENSOR_CHAN_GAUGE_VOLTAGE, &volt,
			   SENSOR_CHAN_GAUGE_AVG_CURRENT, &current,
			   SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE, &v_desired,
			   SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
			   &i_desired,
			   SENSOR_CHAN_GAUGE_STATE_OF_CHARGE, &charge,
			   SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE, &v_design,
			   SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
			   &charge_remain,
			   SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY, &cap,
			   SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY, &nom_cap,
			   SENSOR_CHAN_GAUGE_TIME_TO_FULL, &full,
			   SENSOR_CHAN_GAUGE_TIME_TO_EMPTY, &empty,
			   -1);
	if (err < 0) {
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Temp:  %.1d.%02d C\n", temp.val1,
		      temp.val2 / 10000);
	shell_fprintf(shell, SHELL_NORMAL, "V: %5d.%02d V\n", volt.val1,
		      volt.val2 / 10000);
	shell_fprintf(shell, SHELL_NORMAL, "V-desired: %d.%02d V\n",
		      v_desired.val1, v_desired.val2 / 10000);
	shell_fprintf(shell, SHELL_NORMAL, "I:    %d mA", current.val1);
	if (current.val1 > 0) {
		shell_fprintf(shell, SHELL_NORMAL, " (CHG)");
	} else if (current.val1 < 0) {
		shell_fprintf(shell, SHELL_NORMAL, " (DISCHG)");
	}
	shell_fprintf(shell, SHELL_NORMAL, "\n");
	shell_fprintf(shell, SHELL_NORMAL, "I-desired: %5d mA\n",
		      i_desired.val1);
	allowed = i_desired.val1 && v_desired.val2 && charge.val1 < 100;
	shell_fprintf(shell, SHELL_NORMAL, "Charging: %sAllowed\n",
		      allowed ? "" : "Not ");
	shell_fprintf(shell, SHELL_NORMAL, "Charge: %d %%\n", charge.val1);
	shell_fprintf(shell, SHELL_NORMAL, "V-design: %d.%02d V\n",
		      v_design.val1, v_design.val2 / 10000);
	shell_fprintf(shell, SHELL_NORMAL, "Remaining: %d mA\n",
		      charge_remain.val1);
	shell_fprintf(shell, SHELL_NORMAL, "Cap-full: %d mA\n", cap.val1);
	shell_fprintf(shell, SHELL_NORMAL, "Design: %d mA\n", nom_cap.val1);
	shell_fprintf(shell, SHELL_NORMAL, "Time full: %dh:%02d\n",
		      full.val1 / 60, full.val1 % 60);
	shell_fprintf(shell, SHELL_NORMAL, "Time empty: %dh:%02d\n",
		      empty.val1 / 60, empty.val1 % 60);

	return 0;
}

SHELL_CMD_REGISTER(battery, NULL, "Battery status", cmd_battery);
