/*
 * 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,
				   const 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)
