#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" },
	{}
};

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)
{
	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++) {
		if (rmtfds[i].fd >= 0)
			close(rmtfds[i].fd);
	}
}

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(nbyte, rmtfd->shadow_len - offset);
		if (n > 0)
			memcpy(buf, rmtfd->shadow_buf + offset, n);
		else
			n = 0;
	}

	if (n < nbyte)
		memset(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(rmtfd->shadow_buf + offset, buf, nbyte);

	return nbyte;
}

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;
}
