/*
 * Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <drivers/flash.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

#include "cmdline.h"
#include "soc.h"

#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(flash_native_posix);

static const char default_flash_path[] = "flash.bin";

struct flash_native_posix_data {
	const char *flash_path;
	int fd;
	u8_t *flash;
	bool init_called;
};

struct flash_native_posix_config {
	size_t flash_size;
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
	struct flash_pages_layout layout;
#endif
};

#define DEV_NAME(dev) ((dev)->config->name)
#define DEV_CONFIG(dev) ((dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct flash_native_posix_data *const)(dev)->driver_data)

static int flash_native_posix_read(struct device *dev, off_t offset, void *data,
				   size_t size)
{
	struct flash_native_posix_data *const dev_data = DEV_DATA(dev);
	const struct flash_native_posix_config *config = DEV_CONFIG(dev);

	if (dev_data->flash == MAP_FAILED) {
		LOG_ERR("No flash device mapped");
		return -EIO;
	}

	if ((offset + size) > config->flash_size) {
		LOG_WRN("Reading outside of flash boundaries");
		return -EINVAL;
	}

	memcpy(data, dev_data->flash + offset, size);

	return 0;
}

static int flash_native_posix_write(struct device *dev, off_t offset,
				    const void *data, size_t size)
{
	struct flash_native_posix_data *const dev_data = DEV_DATA(dev);
	const struct flash_native_posix_config *config = DEV_CONFIG(dev);

	if (dev_data->flash == MAP_FAILED) {
		LOG_ERR("No flash device mapped");
		return -EIO;
	}

	if ((offset + size) > config->flash_size) {
		LOG_WRN("Writing outside of flash boundaries");
		return -EINVAL;
	}

	memcpy(dev_data->flash + offset, data, size);

	return 0;
}

static int flash_native_posix_erase(struct device *dev, off_t offset,
				    size_t size)
{
	struct flash_native_posix_data *const dev_data = DEV_DATA(dev);
	const struct flash_native_posix_config *config = DEV_CONFIG(dev);

	if (dev_data->flash == MAP_FAILED) {
		LOG_ERR("No flash device mapped");
		return -EIO;
	}

	if ((offset + size) > config->flash_size) {
		LOG_WRN("Erasing outside of flash boundaries");
		return -EINVAL;
	}

	memset(dev_data->flash + offset, 0xff, size);

	return 0;
}

static int flash_native_posix_write_protection(struct device *dev, bool enable)
{
	return 0;
}

#if defined(CONFIG_FLASH_PAGE_LAYOUT)
static void
flash_native_posix_pages_layout(struct device *dev,
				const struct flash_pages_layout **layout,
				size_t *layout_size)
{
	const struct flash_native_posix_config *config = DEV_CONFIG(dev);
	*layout = &config->layout;
	*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */

static int flash_native_posix_init(struct device *dev)
{
	struct flash_native_posix_data *const data = DEV_DATA(dev);
	const struct flash_native_posix_config *config = DEV_CONFIG(dev);

	data->init_called = true;

	if (data->flash_path == NULL) {
		data->flash_path = default_flash_path;
	}

	data->fd = open(data->flash_path, O_RDWR | O_CREAT, (mode_t)0600);
	if (data->fd == -1) {
		posix_print_warning("Failed to open flash device file "
				    "%s: %s\n",
				    data->flash_path, strerror(errno));
		return -EIO;
	}

	if (ftruncate(data->fd, config->flash_size) == -1) {
		posix_print_warning("Failed to resize flash device file "
				    "%s: %s\n",
				    data->flash_path, strerror(errno));
		return -EIO;
	}

	data->flash = mmap(NULL, config->flash_size,
			   PROT_WRITE | PROT_READ, MAP_SHARED, data->fd, 0);
	if (data->flash == MAP_FAILED) {
		posix_print_warning("Failed to mmap flash device file "
				    "%s: %s\n",
				    data->flash_path, strerror(errno));
		return -EIO;
	}

	LOG_INF("Device %s initialized", DEV_NAME(dev));

	return 0;
}

static const struct flash_driver_api flash_native_posix_driver_api = {
	.read = flash_native_posix_read,
	.write = flash_native_posix_write,
	.erase = flash_native_posix_erase,
	.write_protection = flash_native_posix_write_protection,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
	.page_layout = flash_native_posix_pages_layout,
#endif
	.write_block_size = 1,
};

static const struct flash_native_posix_config flash_native_posix_config = {
	.flash_size = DT_FLASH_SIZE * 1024,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
	.layout = { .pages_count = (DT_FLASH_SIZE * 1024) /
				(CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE * 1024),
		    .pages_size = CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE * 1024
	},
#endif
};

static struct flash_native_posix_data flash_native_posix_data;

DEVICE_AND_API_INIT(flash_native_posix_0, DT_FLASH_DEV_NAME,
		    &flash_native_posix_init, &flash_native_posix_data,
		    &flash_native_posix_config, POST_KERNEL,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &flash_native_posix_driver_api);

static void flash_native_posix_cleanup(void)
{
	struct flash_native_posix_data *const data = &flash_native_posix_data;
	const struct flash_native_posix_config *config =
		&flash_native_posix_config;

	if (!data->init_called) {
		return;
	}

	if (data->flash != MAP_FAILED) {
		munmap(data->flash, config->flash_size);
	}

	if (data->fd != -1) {
		close(data->fd);
	}
}

void flash_native_posix_options(void)
{
	static struct args_struct_t flash_options[] = {
		{ .manual = false,
		  .is_mandatory = false,
		  .is_switch = false,
		  .option = "flash",
		  .name = "path",
		  .type = 's',
		  .dest = (void *)&flash_native_posix_data.flash_path,
		  .call_when_found = NULL,
		  .descript = "Path to binary file to be used as flash" },
		ARG_TABLE_ENDMARKER
	};

	native_add_command_line_opts(flash_options);
}

NATIVE_TASK(flash_native_posix_options, PRE_BOOT_1, 1);
NATIVE_TASK(flash_native_posix_cleanup, ON_EXIT, 1);
