/*
 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

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

/* As we need to be able to keep state for seek, only one file can be open
 * at a time. Make this a structure and point to the entity->info. When we
 * can malloc memory we can change this to support more open files.
 */
typedef struct {
	/* Use the 'in_use' flag as any value for base and file_pos could be
	 * valid.
	 */
	int	in_use;
	size_t	base;
	size_t  file_pos;
} file_state;

static file_state current_file = {0};

/* Identify the device type as memmap */
io_type device_type_memmap(void)
{
	return IO_TYPE_MEMMAP;
}

/* Memmap device functions */
static int memmap_dev_open(void *spec, struct io_dev_info **dev_info);
static int memmap_block_open(struct io_dev_info *dev_info, const void *spec,
			     struct io_entity *entity);
static int memmap_block_seek(struct io_entity *entity, int mode,
			     ssize_t offset);
static int memmap_block_read(struct io_entity *entity, void *buffer,
			     size_t length, size_t *length_read);
static int memmap_block_write(struct io_entity *entity, const void *buffer,
			      size_t length, size_t *length_written);
static int memmap_block_close(struct io_entity *entity);
static int memmap_dev_close(struct io_dev_info *dev_info);


static struct io_dev_connector memmap_dev_connector = {
	.dev_open = memmap_dev_open
};


static struct io_dev_funcs memmap_dev_funcs = {
	.type = device_type_memmap,
	.open = memmap_block_open,
	.seek = memmap_block_seek,
	.size = NULL,
	.read = memmap_block_read,
	.write = memmap_block_write,
	.close = memmap_block_close,
	.dev_init = NULL,
	.dev_close = memmap_dev_close,
};


static struct io_dev_info memmap_dev_info = {
	.funcs = &memmap_dev_funcs,
	.info = (uintptr_t)NULL
};


/* Open a connection to the memmap device */
static int memmap_dev_open(void *spec __attribute__((unused)),
			   struct io_dev_info **dev_info)
{
	assert(dev_info != NULL);
	*dev_info = &memmap_dev_info;

	return IO_SUCCESS;
}



/* Close a connection to the memmap device */
static int memmap_dev_close(struct io_dev_info *dev_info)
{
	/* NOP */
	/* TODO: Consider tracking open files and cleaning them up here */
	return IO_SUCCESS;
}


/* Open a file on the memmap device */
/* TODO: Can we do any sensible limit checks on requested memory */
static int memmap_block_open(struct io_dev_info *dev_info, const void *spec,
			     struct io_entity *entity)
{
	int result = IO_FAIL;
	const io_block_spec *block_spec = (io_block_spec *)spec;

	/* Since we need to track open state for seek() we only allow one open
	 * spec at a time. When we have dynamic memory we can malloc and set
	 * entity->info.
	 */
	if (current_file.in_use == 0) {
		assert(block_spec != NULL);
		assert(entity != NULL);

		current_file.in_use = 1;
		current_file.base = block_spec->offset;
		/* File cursor offset for seek and incremental reads etc. */
		current_file.file_pos = 0;
		entity->info = (uintptr_t)&current_file;
		result = IO_SUCCESS;
	} else {
		ERROR("A Memmap device is already active. Close first.\n");
		result = IO_RESOURCES_EXHAUSTED;
	}

	return result;
}


/* Seek to a particular file offset on the memmap device */
static int memmap_block_seek(struct io_entity *entity, int mode, ssize_t offset)
{
	int result = IO_FAIL;

	/* We only support IO_SEEK_SET for the moment. */
	if (mode == IO_SEEK_SET) {
		assert(entity != NULL);

		/* TODO: can we do some basic limit checks on seek? */
		((file_state *)entity->info)->file_pos = offset;
		result = IO_SUCCESS;
	} else {
		result = IO_FAIL;
	}

	return result;
}


/* Read data from a file on the memmap device */
static int memmap_block_read(struct io_entity *entity, void *buffer,
			     size_t length, size_t *length_read)
{
	file_state *fp;

	assert(entity != NULL);
	assert(buffer != NULL);
	assert(length_read != NULL);

	fp = (file_state *)entity->info;

	memcpy(buffer, (void *)(fp->base + fp->file_pos), length);

	*length_read = length;
	/* advance the file 'cursor' for incremental reads */
	fp->file_pos += length;

	return IO_SUCCESS;
}


/* Write data to a file on the memmap device */
static int memmap_block_write(struct io_entity *entity, const void *buffer,
			      size_t length, size_t *length_written)
{
	file_state *fp;

	assert(entity != NULL);
	assert(buffer != NULL);
	assert(length_written != NULL);

	fp = (file_state *)entity->info;

	memcpy((void *)(fp->base + fp->file_pos), buffer, length);

	*length_written = length;

	/* advance the file 'cursor' for incremental writes */
	fp->file_pos += length;

	return IO_SUCCESS;
}


/* Close a file on the memmap device */
static int memmap_block_close(struct io_entity *entity)
{
	assert(entity != NULL);

	entity->info = 0;

	/* This would be a mem free() if we had malloc.*/
	memset((void *)&current_file, 0, sizeof(current_file));

	return IO_SUCCESS;
}


/* Exported functions */

/* Register the memmap driver with the IO abstraction */
int register_io_dev_memmap(struct io_dev_connector **dev_con)
{
	int result = IO_FAIL;
	assert(dev_con != NULL);

	result = io_register_device(&memmap_dev_info);
	if (result == IO_SUCCESS)
		*dev_con = &memmap_dev_connector;

	return result;
}
