/*
 * Copyright 2022 Google LLC
 * Copyright 2023 Microsoft Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Emulator for SBS 1.1 compliant smart battery fuel gauge.
 */

#ifdef CONFIG_FUEL_GAUGE
#define DT_DRV_COMPAT sbs_sbs_gauge_new_api
#else
#define DT_DRV_COMPAT sbs_sbs_gauge
#endif /* CONFIG_FUEL_GAUGE */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sbs_sbs_gauge);

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/fuel_gauge.h>

#include "sbs_gauge.h"

/** Run-time data used by the emulator */
struct sbs_gauge_emul_data {
	uint16_t mfr_acc;
	uint16_t remaining_capacity_alarm;
	uint16_t remaining_time_alarm;
	uint16_t mode;
	int16_t at_rate;
};

/** Static configuration for the emulator */
struct sbs_gauge_emul_cfg {
	/** I2C address of emulator */
	uint16_t addr;
};

static int emul_sbs_gauge_reg_write(const struct emul *target, int reg, int val)
{
	struct sbs_gauge_emul_data *data = target->data;

	LOG_INF("write %x = %x", reg, val);
	switch (reg) {
	case SBS_GAUGE_CMD_MANUFACTURER_ACCESS:
		data->mfr_acc = val;
		break;
	case SBS_GAUGE_CMD_REM_CAPACITY_ALARM:
		data->remaining_capacity_alarm = val;
		break;
	case SBS_GAUGE_CMD_REM_TIME_ALARM:
		data->remaining_time_alarm = val;
		break;
	case SBS_GAUGE_CMD_BATTERY_MODE:
		data->mode = val;
		break;
	case SBS_GAUGE_CMD_AR:
		data->at_rate = val;
		break;
	default:
		LOG_INF("Unknown write %x", reg);
		return -EIO;
	}

	return 0;
}

static int emul_sbs_gauge_reg_read(const struct emul *target, int reg, int *val)
{
	struct sbs_gauge_emul_data *data = target->data;

	switch (reg) {
	case SBS_GAUGE_CMD_MANUFACTURER_ACCESS:
		*val = data->mfr_acc;
		break;
	case SBS_GAUGE_CMD_REM_CAPACITY_ALARM:
		*val = data->remaining_capacity_alarm;
		break;
	case SBS_GAUGE_CMD_REM_TIME_ALARM:
		*val = data->remaining_time_alarm;
		break;
	case SBS_GAUGE_CMD_BATTERY_MODE:
		*val = data->mode;
		break;
	case SBS_GAUGE_CMD_AR:
		*val = data->at_rate;
		break;
	case SBS_GAUGE_CMD_VOLTAGE:
	case SBS_GAUGE_CMD_AVG_CURRENT:
	case SBS_GAUGE_CMD_TEMP:
	case SBS_GAUGE_CMD_ASOC:
	case SBS_GAUGE_CMD_RSOC:
	case SBS_GAUGE_CMD_FULL_CAPACITY:
	case SBS_GAUGE_CMD_REM_CAPACITY:
	case SBS_GAUGE_CMD_NOM_CAPACITY:
	case SBS_GAUGE_CMD_AVG_TIME2EMPTY:
	case SBS_GAUGE_CMD_AVG_TIME2FULL:
	case SBS_GAUGE_CMD_RUNTIME2EMPTY:
	case SBS_GAUGE_CMD_CYCLE_COUNT:
	case SBS_GAUGE_CMD_DESIGN_VOLTAGE:
	case SBS_GAUGE_CMD_CURRENT:
	case SBS_GAUGE_CMD_CHG_CURRENT:
	case SBS_GAUGE_CMD_CHG_VOLTAGE:
	case SBS_GAUGE_CMD_FLAGS:
	case SBS_GAUGE_CMD_ARTTF:
	case SBS_GAUGE_CMD_ARTTE:
	case SBS_GAUGE_CMD_AROK:
		/* Arbitrary stub value. */
		*val = 1;
		break;
	default:
		LOG_ERR("Unknown register 0x%x read", reg);
		return -EIO;
	}
	LOG_INF("read 0x%x = 0x%x", reg, *val);

	return 0;
}

static int emul_sbs_gauge_buffer_read(const struct emul *target, int reg, char *val)
{
	char mfg[] = "ACME";
	char dev[] = "B123456";
	char chem[] = "LiPO";
	struct sbs_gauge_manufacturer_name *mfg_name = (struct sbs_gauge_manufacturer_name *)val;
	struct sbs_gauge_device_name *dev_name = (struct sbs_gauge_device_name *)val;
	struct sbs_gauge_device_chemistry *dev_chem = (struct sbs_gauge_device_chemistry *)val;

	switch (reg) {
	case SBS_GAUGE_CMD_MANUFACTURER_NAME:
		mfg_name->manufacturer_name_length = sizeof(mfg);
		memcpy(mfg_name->manufacturer_name, mfg, mfg_name->manufacturer_name_length);
		break;
	case SBS_GAUGE_CMD_DEVICE_NAME:
		dev_name->device_name_length = sizeof(dev);
		memcpy(dev_name->device_name, dev, dev_name->device_name_length);
		break;

	case SBS_GAUGE_CMD_DEVICE_CHEMISTRY:
		dev_chem->device_chemistry_length = MIN(sizeof(chem),
							sizeof(dev_chem->device_chemistry));
		memcpy(dev_chem->device_chemistry, chem, dev_chem->device_chemistry_length);
		break;
	default:
		LOG_ERR("Unknown register 0x%x read", reg);
		return -EIO;
	}

	return 0;
}

static int sbs_gauge_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
				       int num_msgs, int addr)
{
	/* Largely copied from emul_bmi160.c */
	struct sbs_gauge_emul_data *data;
	unsigned int val;
	int reg;
	int rc;

	data = target->data;

	__ASSERT_NO_MSG(msgs && num_msgs);

	i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
	switch (num_msgs) {
	case 2:
		if (msgs->flags & I2C_MSG_READ) {
			LOG_ERR("Unexpected read");
			return -EIO;
		}
		if (msgs->len != 1) {
			LOG_ERR("Unexpected msg0 length %d", msgs->len);
			return -EIO;
		}
		reg = msgs->buf[0];

		/* Now process the 'read' part of the message */
		msgs++;
		if (msgs->flags & I2C_MSG_READ) {
			switch (msgs->len) {
			case 2:
				rc = emul_sbs_gauge_reg_read(target, reg, &val);
				if (rc) {
					/* Return before writing bad value to message buffer */
					return rc;
				}

				/* SBS uses SMBus, which sends data in little-endian format. */
				sys_put_le16(val, msgs->buf);
				break;
					/* buffer properties */
			case (sizeof(struct sbs_gauge_manufacturer_name)):
			case (sizeof(struct sbs_gauge_device_chemistry)):
				rc = emul_sbs_gauge_buffer_read(target, reg, (char *)msgs->buf);
				break;
			default:
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
				return -EIO;
			}
		} else {
			/* We write a word (2 bytes by the SBS spec) */
			if (msgs->len != 2) {
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
			}
			uint16_t value = sys_get_le16(msgs->buf);

			rc = emul_sbs_gauge_reg_write(target, reg, value);
		}
		break;
	default:
		LOG_ERR("Invalid number of messages: %d", num_msgs);
		return -EIO;
	}

	return rc;
}

static const struct i2c_emul_api sbs_gauge_emul_api_i2c = {
	.transfer = sbs_gauge_emul_transfer_i2c,
};

/**
 * Set up a new SBS_GAUGE emulator (I2C)
 *
 * @param emul Emulation information
 * @param parent Device to emulate (must use sbs_gauge driver)
 * @return 0 indicating success (always)
 */
static int emul_sbs_sbs_gauge_init(const struct emul *target, const struct device *parent)
{
	ARG_UNUSED(target);
	ARG_UNUSED(parent);

	return 0;
}

/*
 * Main instantiation macro. SBS Gauge Emulator only implemented for I2C
 */
#define SBS_GAUGE_EMUL(n)                                                                          \
	static struct sbs_gauge_emul_data sbs_gauge_emul_data_##n;                                 \
	static const struct sbs_gauge_emul_cfg sbs_gauge_emul_cfg_##n = {                          \
		.addr = DT_INST_REG_ADDR(n),                                                       \
	};                                                                                         \
	EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_gauge_init, &sbs_gauge_emul_data_##n,                  \
			    &sbs_gauge_emul_cfg_##n, &sbs_gauge_emul_api_i2c, NULL)

DT_INST_FOREACH_STATUS_OKAY(SBS_GAUGE_EMUL)
