#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "rmtfs.h"

#define MAX_CALLERS 10
#define STORAGE_MAX_SIZE (16 * 1024 * 1024)

#define BY_PARTLABEL_PATH "/dev/disk/by-partlabel"

#define MIN(x, y) ((x) < (y) ? (x) : (y))

struct partition {
	const char *path;
	const char *actual;
	const char *partlabel;
};

struct rmtfd {
	unsigned id;
	unsigned node;
	int fd;
	unsigned dev_error;
	const struct partition *partition;

	void *shadow_buf;
	size_t shadow_len;
};

static const char *storage_dir = "/boot";
static int storage_read_only;
static int storage_use_partitions;

static const struct partition partition_table[] = {
	{ "/boot/modem_fs1", "modem_fs1", "modemst1" },
	{ "/boot/modem_fs2", "modem_fs2", "modemst2" },
	{ "/boot/modem_fsc", "modem_fsc", "fsc" },
	{ "/boot/modem_fsg", "modem_fsg", "fsg" },
	{ "/boot/modem_tunning", "modem_tunning", "tunning" },
	{}
};

static struct rmtfd rmtfds[MAX_CALLERS];

static int storage_populate_shadow_buf(struct rmtfd *rmtfd, const char *file);

int storage_init(const char *storage_root, bool read_only, bool use_partitions)
{
	int i;

	if (storage_root)
		storage_dir = storage_root;

	if (use_partitions) {
		if (!storage_root)
			storage_dir = BY_PARTLABEL_PATH;
		storage_use_partitions = true;
	}

	storage_read_only = read_only;

	for (i = 0; i < MAX_CALLERS; i++) {
		rmtfds[i].id = i;
		rmtfds[i].fd = -1;
		rmtfds[i].shadow_buf = NULL;
	}

	return 0;
}

struct rmtfd *storage_open(unsigned node, const char *path)
{
	char *fspath;
	const struct partition *part;
	struct rmtfd *rmtfd = NULL;
	const char *file;
	size_t pathlen;
	int saved_errno;
	int ret;
	int fd;
	int i;

	for (part = partition_table; part->path; part++) {
		if (strcmp(part->path, path) == 0)
			goto found;
	}

	fprintf(stderr, "[RMTFS storage] request for unknown partition '%s', rejecting\n", path);
	return NULL;

found:
	/* Check if this node already has the requested path open */
	for (i = 0; i < MAX_CALLERS; i++) {
		if ((rmtfds[i].fd != -1 || rmtfds[i].shadow_buf) &&
		    rmtfds[i].node == node &&
		    rmtfds[i].partition == part)
			return &rmtfds[i];
	}

	for (i = 0; i < MAX_CALLERS; i++) {
		if (rmtfds[i].fd == -1 && !rmtfds[i].shadow_buf) {
			rmtfd = &rmtfds[i];
			break;
		}
	}
	if (!rmtfd) {
		fprintf(stderr, "[storage] out of free rmtfd handles\n");
		return NULL;
	}

	if (storage_use_partitions)
		file = part->partlabel;
	else
		file = part->actual;

	pathlen = strlen(storage_dir) + strlen(file) + 2;
	fspath = alloca(pathlen);
	snprintf(fspath, pathlen, "%s/%s", storage_dir, file);
	if (!storage_read_only) {
		fd = open(fspath, O_RDWR);
		if (fd < 0) {
			saved_errno = errno;
			fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
					fspath, part->path, strerror(saved_errno));
			errno = saved_errno;
			return NULL;
		}
		rmtfd->fd = fd;
		rmtfd->shadow_len = 0;
	} else {
		ret = storage_populate_shadow_buf(rmtfd, fspath);
		if (ret < 0) {
			saved_errno = errno;
			fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
					fspath, part->path, strerror(saved_errno));
			errno = saved_errno;
			return NULL;
		}
	}

	rmtfd->node = node;
	rmtfd->partition = part;

	return rmtfd;
}

void storage_close(struct rmtfd *rmtfd)
{
	if (rmtfd->fd >= 0) {
		close(rmtfd->fd);
		rmtfd->fd = -1;
	}

	free(rmtfd->shadow_buf);
	rmtfd->shadow_buf = NULL;
	rmtfd->shadow_len = 0;

	rmtfd->partition = NULL;
}

struct rmtfd *storage_get(unsigned node, int caller_id)
{
	struct rmtfd *rmtfd;

	if (caller_id >= MAX_CALLERS)
		return NULL;

	rmtfd = &rmtfds[caller_id];
	if (rmtfd->node != node)
		return NULL;

	return rmtfd;
}

int storage_get_caller_id(const struct rmtfd *rmtfd)
{
	return rmtfd->id;
}

int storage_get_error(const struct rmtfd *rmtfd)
{
	return rmtfd->dev_error;
}

void storage_exit(void)
{
	int i;

	for (i = 0; i < MAX_CALLERS; i++)
		storage_close(&rmtfds[i]);
}

ssize_t storage_pread(const struct rmtfd *rmtfd, void *buf, size_t nbyte, off_t offset)
{
	ssize_t n;

	if (!storage_read_only) {
		n = pread(rmtfd->fd, buf, nbyte, offset);
	} else {
		n = MIN((ssize_t)nbyte, (ssize_t)rmtfd->shadow_len - offset);
		if (n > 0)
			memcpy(buf, (char*)rmtfd->shadow_buf + offset, n);
		else
			n = 0;
	}

	if (n < nbyte)
		memset((char*)buf + n, 0, nbyte - n);

	return nbyte;
}

ssize_t storage_pwrite(struct rmtfd *rmtfd, const void *buf, size_t nbyte, off_t offset)
{
	size_t new_len = offset + nbyte;
	void *new_buf;

	if (!storage_read_only)
		return pwrite(rmtfd->fd, buf, nbyte, offset);

	if (new_len >= STORAGE_MAX_SIZE) {
		fprintf(stderr, "write to %zd bytes exceededs max size\n", new_len);
		errno = -EINVAL;
		return -1;
	}

	if (new_len > rmtfd->shadow_len) {
		new_buf = realloc(rmtfd->shadow_buf, new_len);
		if (!new_buf) {
			errno = -ENOMEM;
			return -1;
		}

		rmtfd->shadow_buf = new_buf;
		rmtfd->shadow_len = new_len;
	}

	memcpy((char*)rmtfd->shadow_buf + offset, buf, nbyte);

	return nbyte;
}

int storage_sync(struct rmtfd *rmtfd)
{
	if (storage_read_only)
		return 0;
	
	return fdatasync(rmtfd->fd);
}

static int storage_populate_shadow_buf(struct rmtfd *rmtfd, const char *file)
{
	ssize_t len;
	ssize_t n;
	void *buf;
	int ret;
	int fd;

	fd = open(file, O_RDONLY);
	if (fd < 0)
		return -1;

	len = lseek(fd, 0, SEEK_END);
	if (len < 0) {
		ret = -1;
		goto err_close_fd;
	}

	lseek(fd, 0, SEEK_SET);

	buf = calloc(1, len);
	if (!buf) {
		ret = -1;
		goto err_close_fd;
	}

	n = read(fd, buf, len);
	if (n < 0) {
		ret = -1;
		goto err_close_fd;
	}

	rmtfd->shadow_buf = buf;
	rmtfd->shadow_len = n;

	ret = 0;

err_close_fd:
	close(fd);

	return ret;
}
