/*
 * Copyright (c) 2023 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT fintek_f75303

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/emul_sensor.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/sensor/f75303.h>
#include "f75303.h"

LOG_MODULE_DECLARE(F75303, CONFIG_SENSOR_LOG_LEVEL);

#define NUM_REGS 128

struct f75303_emul_data {
	uint8_t reg[NUM_REGS];
};

struct f75303_emul_cfg {
};

static void f75303_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val)
{
	struct f75303_emul_data *data = target->data;

	__ASSERT_NO_MSG(reg < NUM_REGS);
	data->reg[reg] = val;
}

static uint8_t f75303_emul_get_reg(const struct emul *target, uint8_t reg)
{
	struct f75303_emul_data *data = target->data;

	__ASSERT_NO_MSG(reg < NUM_REGS);
	return data->reg[reg];
}

static void f75303_emul_reset(const struct emul *target)
{
	struct f75303_emul_data *data = target->data;

	memset(data->reg, 0, NUM_REGS);
}

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

	__ASSERT_NO_MSG(msgs && num_msgs);

	i2c_dump_msgs_rw(target->dev, 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 1:
				val = f75303_emul_get_reg(target, reg);
				msgs->buf[0] = val;
				break;
			default:
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
				return -EIO;
			}
		} else {
			if (msgs->len != 1) {
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
			}
			f75303_emul_set_reg(target, reg, msgs->buf[0]);
		}
		break;
	default:
		LOG_ERR("Invalid number of messages: %d", num_msgs);
		return -EIO;
	}

	return 0;
}

static int f75303_emul_init(const struct emul *target, const struct device *parent)
{
	f75303_emul_reset(target);
	return 0;
}

static int f75303_emul_set_channel(const struct emul *target, enum sensor_channel chan,
				   q31_t value, int8_t shift)
{
	struct f75303_emul_data *data = target->data;
	int64_t scaled_value;
	int32_t millicelsius;
	int32_t reg_value;
	uint8_t reg_h, reg_l;

	switch ((int32_t)chan) {
	case SENSOR_CHAN_AMBIENT_TEMP:
		reg_h = F75303_LOCAL_TEMP_H;
		reg_l = F75303_LOCAL_TEMP_L;
		break;
	case SENSOR_CHAN_F75303_REMOTE1:
		reg_h = F75303_REMOTE1_TEMP_H;
		reg_l = F75303_REMOTE1_TEMP_L;
		break;
	case SENSOR_CHAN_F75303_REMOTE2:
		reg_h = F75303_REMOTE2_TEMP_H;
		reg_l = F75303_REMOTE2_TEMP_L;
		break;
	default:
		return -ENOTSUP;
	}

	scaled_value = (int64_t)value << shift;
	millicelsius = scaled_value * 1000 / ((int64_t)INT32_MAX + 1);
	reg_value = CLAMP(millicelsius / 125, 0, 0x7ff);

	data->reg[reg_h] = reg_value >> 3;
	data->reg[reg_l] = (reg_value & 0x7) << 5;

	return 0;
}

static int f75303_emul_get_sample_range(const struct emul *target, enum sensor_channel chan,
					q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift)
{
	if (chan != SENSOR_CHAN_AMBIENT_TEMP &&
	    chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE1 &&
	    chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE2) {
		return -ENOTSUP;
	}

	*shift = 8;
	*lower = 0;
	*upper = (int64_t)(255.875 * ((int64_t)INT32_MAX + 1)) >> *shift;
	*epsilon = (int64_t)(0.125 * ((int64_t)INT32_MAX + 1)) >> *shift;

	return 0;
}

static const struct i2c_emul_api f75303_emul_api_i2c = {
	.transfer = f75303_emul_transfer_i2c,
};

static const struct emul_sensor_backend_api f75303_emul_api_sensor = {
	.set_channel = f75303_emul_set_channel,
	.get_sample_range = f75303_emul_get_sample_range,
};


#define F75303_EMUL(n)								\
	const struct f75303_emul_cfg f75303_emul_cfg_##n;			\
	struct f75303_emul_data f75303_emul_data_##n;				\
	EMUL_DT_INST_DEFINE(n, f75303_emul_init, &f75303_emul_data_##n,		\
			    &f75303_emul_cfg_##n, &f75303_emul_api_i2c,		\
			    &f75303_emul_api_sensor);

DT_INST_FOREACH_STATUS_OKAY(F75303_EMUL)
