/*
 * Copyright (c) 2017 BayLibre, SAS
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <string.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(main);

#include <zephyr.h>
#include <device.h>
#include <stdio.h>
#include <sys/util.h>

#include <drivers/i2c.h>
#include <drivers/i2c/slave/eeprom.h>

#include <ztest.h>

#define TEST_DATA_SIZE	20

static u8_t eeprom_0_data[TEST_DATA_SIZE] = "0123456789abcdefghij";
static u8_t eeprom_1_data[TEST_DATA_SIZE] = "jihgfedcba9876543210";
static u8_t i2c_buffer[TEST_DATA_SIZE];

/*
 * We need 5x(buffer size) + 1 to print a comma-separated list of each
 * byte in hex, plus a null.
 */
u8_t buffer_print_eeprom[TEST_DATA_SIZE * 5 + 1];
u8_t buffer_print_i2c[TEST_DATA_SIZE * 5 + 1];

static void to_display_format(const u8_t *src, size_t size, char *dst)
{
	size_t i;

	for (i = 0; i < size; i++) {
		sprintf(dst + 5 * i, "0x%02x,", src[i]);
	}
}

static void run_full_read(struct device *i2c, u8_t addr, u8_t *comp_buffer)
{
	int ret;

	LOG_INF("Start full read. Master: %s, address: 0x%x",
		    i2c->name, addr);

	/* Read EEPROM from I2C Master requests, then compare */
	ret = i2c_burst_read(i2c, addr,
			     0, i2c_buffer, TEST_DATA_SIZE);
	zassert_equal(ret, 0, "Failed to read EEPROM");

	if (memcmp(i2c_buffer, comp_buffer, TEST_DATA_SIZE)) {
		to_display_format(i2c_buffer, TEST_DATA_SIZE,
				  buffer_print_i2c);
		to_display_format(comp_buffer, TEST_DATA_SIZE,
				  buffer_print_eeprom);
		LOG_ERR("Buffer contents are different: %s",
			    buffer_print_i2c);
		LOG_ERR("                           vs: %s",
			    buffer_print_eeprom);

		ztest_test_fail();
	}
}

static void run_partial_read(struct device *i2c, u8_t addr, u8_t *comp_buffer,
			     unsigned int offset)
{
	int ret;

	LOG_INF("Start partial read. Master: %s, address: 0x%x, off=%d",
		    i2c->name, addr, offset);

	ret = i2c_burst_read(i2c, addr,
			     offset, i2c_buffer, TEST_DATA_SIZE-offset);
	zassert_equal(ret, 0, "Failed to read EEPROM");

	if (memcmp(i2c_buffer, &comp_buffer[offset], TEST_DATA_SIZE-offset)) {
		to_display_format(i2c_buffer, TEST_DATA_SIZE-offset,
				  buffer_print_i2c);
		to_display_format(&comp_buffer[offset], TEST_DATA_SIZE-offset,
				  buffer_print_eeprom);
		LOG_ERR("Buffer contents are different: %s",
			    buffer_print_i2c);
		LOG_ERR("                           vs: %s",
			    buffer_print_eeprom);

		ztest_test_fail();
	}
}

static void run_program_read(struct device *i2c, u8_t addr, unsigned int offset)
{
	int ret, i;

	LOG_INF("Start program. Master: %s, address: 0x%x, off=%d",
		    i2c->name, addr, offset);

	for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) {
		i2c_buffer[i] = i;
	}

	ret = i2c_burst_write(i2c, addr,
			      offset, i2c_buffer, TEST_DATA_SIZE-offset);
	zassert_equal(ret, 0, "Failed to write EEPROM");

	(void)memset(i2c_buffer, 0xFF, TEST_DATA_SIZE);

	/* Read back EEPROM from I2C Master requests, then compare */
	ret = i2c_burst_read(i2c, addr,
			     offset, i2c_buffer, TEST_DATA_SIZE-offset);
	zassert_equal(ret, 0, "Failed to read EEPROM");

	for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) {
		if (i2c_buffer[i] != i) {
			to_display_format(i2c_buffer, TEST_DATA_SIZE-offset,
					  buffer_print_i2c);
			LOG_ERR("Invalid Buffer content: %s",
				    buffer_print_i2c);

			ztest_test_fail();
		}
	}
}

void test_eeprom_slave(void)
{
	struct device *eeprom_0;
	struct device *eeprom_1;
	struct device *i2c_0;
	struct device *i2c_1;
	int ret, offset;


	i2c_0 = device_get_binding(
			DT_BUS_LABEL(DT_INST(0, atmel_at24)));
	zassert_not_null(i2c_0, "I2C device %s not found",
			 DT_BUS_LABEL(DT_INST(0, atmel_at24)));

	LOG_INF("Found I2C Master device %s",
		    DT_BUS_LABEL(DT_INST(0, atmel_at24)));

	i2c_1 = device_get_binding(
			DT_BUS_LABEL(DT_INST(1, atmel_at24)));
	zassert_not_null(i2c_1, "I2C device %s not found",
			 DT_BUS_LABEL(DT_INST(1, atmel_at24)));

	LOG_INF("Found I2C Master device %s",
		    DT_BUS_LABEL(DT_INST(1, atmel_at24)));

	/*
	 * Normal applications would interact with an EEPROM
	 * identified by the string literal used in the binding node
	 * label property ("EEPROM_SLAVE_0") rather than the generated
	 * macro DT_LABEL(DT_INST(0, atmel_at24)).  There is no guarantee that
	 * the index for the compatible is persistent across builds;
	 * for example DT_LABEL(DT_INST(0, atmel_at24)) might refer to
	 * "EEPROM_SLAVE_1" * if the order of the node declarations were changed
	 * in the overlay file.
	 *
	 * The label string cannot be directly used to determine the
	 * correct parent bus and device index for whitebox testing in
	 * this application.  So for this application only, where the
	 * devices are interchangeable, the device is selected the
	 * using the generated macro.
	 */

	eeprom_0 = device_get_binding(DT_LABEL(DT_INST(0, atmel_at24)));
	zassert_not_null(eeprom_0, "EEPROM device %s not found",
			 DT_LABEL(DT_INST(0, atmel_at24)));

	LOG_INF("Found EEPROM device %s", DT_LABEL(DT_INST(0, atmel_at24)));

	eeprom_1 = device_get_binding(DT_LABEL(DT_INST(1, atmel_at24)));
	zassert_not_null(eeprom_1, "EEPROM device %s not found",
			 DT_LABEL(DT_INST(1, atmel_at24)));

	LOG_INF("Found EEPROM device %s", DT_LABEL(DT_INST(1, atmel_at24)));

	/* Program dummy bytes */
	ret = eeprom_slave_program(eeprom_0, eeprom_0_data, TEST_DATA_SIZE);
	zassert_equal(ret, 0, "Failed to program EEPROM %s",
		      DT_LABEL(DT_INST(0, atmel_at24)));

	ret = eeprom_slave_program(eeprom_1, eeprom_1_data, TEST_DATA_SIZE);
	zassert_equal(ret, 0, "Failed to program EEPROM %s",
		      DT_LABEL(DT_INST(1, atmel_at24)));

	/* Attach EEPROM */
	ret = i2c_slave_driver_register(eeprom_0);
	zassert_equal(ret, 0, "Failed to register EEPROM %s",
		      DT_LABEL(DT_INST(0, atmel_at24)));

	LOG_INF("EEPROM %s Attached !", DT_LABEL(DT_INST(0, atmel_at24)));

	ret = i2c_slave_driver_register(eeprom_1);
	zassert_equal(ret, 0, "Failed to register EEPROM %s",
		      DT_LABEL(DT_INST(1, atmel_at24)));

	LOG_INF("EEPROM %s Attached !", DT_LABEL(DT_INST(1, atmel_at24)));

	/* Run Tests without bus access conflicts */
	run_full_read(i2c_0, DT_REG_ADDR(DT_INST(1, atmel_at24)), eeprom_1_data);
	run_full_read(i2c_1, DT_REG_ADDR(DT_INST(0, atmel_at24)), eeprom_0_data);

	for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) {
		run_partial_read(i2c_0, DT_REG_ADDR(DT_INST(1, atmel_at24)),
				 eeprom_1_data, offset);
	}

	for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) {
		run_partial_read(i2c_1, DT_REG_ADDR(DT_INST(0, atmel_at24)),
				 eeprom_0_data, offset);
	}

	for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) {
		run_program_read(i2c_0, DT_REG_ADDR(DT_INST(1, atmel_at24)),
				 offset);
	}

	for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) {
		run_program_read(i2c_1, DT_REG_ADDR(DT_INST(0, atmel_at24)),
				 offset);
	}

	LOG_INF("Success !");

	/* Detach EEPROM */
	ret = i2c_slave_driver_unregister(eeprom_0);
	zassert_equal(ret, 0, "Failed to unregister EEPROM %s",
		      DT_LABEL(DT_INST(0, atmel_at24)));

	LOG_INF("EEPROM %s Detached !",
		    DT_LABEL(DT_INST(0, atmel_at24)));

	ret = i2c_slave_driver_unregister(eeprom_1);
	zassert_equal(ret, 0, "Failed to unregister EEPROM %s",
		      DT_LABEL(DT_INST(1, atmel_at24)));

	LOG_INF("EEPROM %s Detached !",
		    DT_LABEL(DT_INST(1, atmel_at24)));
}

void test_main(void)
{
	ztest_test_suite(test_eeprom_slave, ztest_unit_test(test_eeprom_slave));
	ztest_run_test_suite(test_eeprom_slave);
}
