/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <debug.h>
#include <io_driver.h>
#include <io_dummy.h>
#include <io_storage.h>
#include <string.h>

struct file_state {
	int in_use;
	size_t size;
};

static struct file_state current_file = {0};

/* Identify the device type as dummy */
static io_type_t device_type_dummy(void)
{
	return IO_TYPE_DUMMY;
}

/* Dummy device functions */
static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
			     io_entity_t *entity);
static int dummy_block_len(io_entity_t *entity, size_t *length);
static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
			     size_t length, size_t *length_read);
static int dummy_block_close(io_entity_t *entity);
static int dummy_dev_close(io_dev_info_t *dev_info);


static const io_dev_connector_t dummy_dev_connector = {
	.dev_open = dummy_dev_open
};


static const io_dev_funcs_t dummy_dev_funcs = {
	.type = device_type_dummy,
	.open = dummy_block_open,
	.seek = NULL,
	.size = dummy_block_len,
	.read = dummy_block_read,
	.write = NULL,
	.close = dummy_block_close,
	.dev_init = NULL,
	.dev_close = dummy_dev_close,
};


static const io_dev_info_t dummy_dev_info = {
	.funcs = &dummy_dev_funcs,
	.info = (uintptr_t)NULL
};


/* Open a connection to the dummy device */
static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
			   io_dev_info_t **dev_info)
{
	assert(dev_info != NULL);
	*dev_info = (io_dev_info_t *)&dummy_dev_info;

	return 0;
}


/* Close a connection to the dummy device */
static int dummy_dev_close(io_dev_info_t *dev_info)
{
	return 0;
}


/* Open a file on the dummy device */
static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
			     io_entity_t *entity)
{
	int result;
	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;

	if (current_file.in_use == 0) {
		assert(block_spec != NULL);
		assert(entity != NULL);

		current_file.in_use = 1;
		current_file.size = block_spec->length;
		entity->info = (uintptr_t)&current_file;
		result = 0;
	} else {
		WARN("A Dummy device is already active. Close first.\n");
		result = -ENOMEM;
	}

	return result;
}


/* Return the size of a file on the dummy device */
static int dummy_block_len(io_entity_t *entity, size_t *length)
{
	assert(entity != NULL);
	assert(length != NULL);

	*length =  ((struct file_state *)entity->info)->size;

	return 0;
}


/* Read data from a file on the dummy device */
static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
			     size_t length, size_t *length_read)
{
	assert(length_read != NULL);

	*length_read = length;

	return 0;
}


/* Close a file on the dummy device */
static int dummy_block_close(io_entity_t *entity)
{
	assert(entity != NULL);

	entity->info = 0;
	current_file.in_use = 0;

	return 0;
}


/* Exported functions */

/* Register the dummy driver with the IO abstraction */
int register_io_dev_dummy(const io_dev_connector_t **dev_con)
{
	int result;

	assert(dev_con != NULL);

	result = io_register_device(&dummy_dev_info);
	if (result == 0)
		*dev_con = &dummy_dev_connector;

	return result;
}
