/*
  FUSE: Filesystem in Userspace
  Copyright (C) 2010  Miklos Szeredi <miklos@szeredi.hu>

  This program can be distributed under the terms of the GNU LGPLv2.
  See the file COPYING.LIB
*/

#define _GNU_SOURCE

#include "config.h"
#include "fuse_i.h"
#include "fuse_lowlevel.h"
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>

size_t fuse_buf_size(const struct fuse_bufvec *bufv)
{
	size_t i;
	size_t size = 0;

	for (i = 0; i < bufv->count; i++) {
		if (bufv->buf[i].size == SIZE_MAX)
			size = SIZE_MAX;
		else
			size += bufv->buf[i].size;
	}

	return size;
}

static size_t min_size(size_t s1, size_t s2)
{
	return s1 < s2 ? s1 : s2;
}

static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
			      const struct fuse_buf *src, size_t src_off,
			      size_t len)
{
	ssize_t res = 0;
	size_t copied = 0;

	while (len) {
		if (dst->flags & FUSE_BUF_FD_SEEK) {
			res = pwrite(dst->fd, src->mem + src_off, len,
				     dst->pos + dst_off);
		} else {
			res = write(dst->fd, src->mem + src_off, len);
		}
		if (res == -1) {
			if (!copied)
				return -errno;
			break;
		}
		if (res == 0)
			break;

		copied += res;
		if (!(dst->flags & FUSE_BUF_FD_RETRY))
			break;

		src_off += res;
		dst_off += res;
		len -= res;
	}

	return copied;
}

static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
			     const struct fuse_buf *src, size_t src_off,
			     size_t len)
{
	ssize_t res = 0;
	size_t copied = 0;

	while (len) {
		if (src->flags & FUSE_BUF_FD_SEEK) {
			res = pread(src->fd, dst->mem + dst_off, len,
				     src->pos + src_off);
		} else {
			res = read(src->fd, dst->mem + dst_off, len);
		}
		if (res == -1) {
			if (!copied)
				return -errno;
			break;
		}
		if (res == 0)
			break;

		copied += res;
		if (!(src->flags & FUSE_BUF_FD_RETRY))
			break;

		dst_off += res;
		src_off += res;
		len -= res;
	}

	return copied;
}

static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
				 const struct fuse_buf *src, size_t src_off,
				 size_t len)
{
	char buf[4096];
	struct fuse_buf tmp = {
		.size = sizeof(buf),
		.flags = 0,
	};
	ssize_t res;
	size_t copied = 0;

	tmp.mem = buf;

	while (len) {
		size_t this_len = min_size(tmp.size, len);
		size_t read_len;

		res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
		if (res < 0) {
			if (!copied)
				return res;
			break;
		}
		if (res == 0)
			break;

		read_len = res;
		res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
		if (res < 0) {
			if (!copied)
				return res;
			break;
		}
		if (res == 0)
			break;

		copied += res;

		if (res < this_len)
			break;

		dst_off += res;
		src_off += res;
		len -= res;
	}

	return copied;
}

#ifdef HAVE_SPLICE
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
			       const struct fuse_buf *src, size_t src_off,
			       size_t len, enum fuse_buf_copy_flags flags)
{
	int splice_flags = 0;
	off64_t *srcpos = NULL;
	off64_t *dstpos = NULL;
	off64_t srcpos_val;
	off64_t dstpos_val;
	ssize_t res;
	size_t copied = 0;

	if (flags & FUSE_BUF_SPLICE_MOVE)
		splice_flags |= SPLICE_F_MOVE;
	if (flags & FUSE_BUF_SPLICE_NONBLOCK)
		splice_flags |= SPLICE_F_NONBLOCK;

	if (src->flags & FUSE_BUF_FD_SEEK) {
		srcpos_val = src->pos + src_off;
		srcpos = &srcpos_val;
	}
	if (dst->flags & FUSE_BUF_FD_SEEK) {
		dstpos_val = dst->pos + dst_off;
		dstpos = &dstpos_val;
	}

	while (len) {
		res = splice(src->fd, srcpos, dst->fd, dstpos, len,
			     splice_flags);
		if (res == -1) {
			if (copied)
				break;

			if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE))
				return -errno;

			/* Maybe splice is not supported for this combination */
			return fuse_buf_fd_to_fd(dst, dst_off, src, src_off,
						 len);
		}
		if (res == 0)
			break;

		copied += res;
		if (!(src->flags & FUSE_BUF_FD_RETRY) &&
		    !(dst->flags & FUSE_BUF_FD_RETRY)) {
			break;
		}

		len -= res;
	}

	return copied;
}
#else
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
			       const struct fuse_buf *src, size_t src_off,
			       size_t len, enum fuse_buf_copy_flags flags)
{
	(void) flags;

	return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
}
#endif


static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
				 const struct fuse_buf *src, size_t src_off,
				 size_t len, enum fuse_buf_copy_flags flags)
{
	int src_is_fd = src->flags & FUSE_BUF_IS_FD;
	int dst_is_fd = dst->flags & FUSE_BUF_IS_FD;

	if (!src_is_fd && !dst_is_fd) {
		void *dstmem = dst->mem + dst_off;
		void *srcmem = src->mem + src_off;

		if (dstmem != srcmem) {
			if (dstmem + len <= srcmem || srcmem + len <= dstmem)
				memcpy(dstmem, srcmem, len);
			else
				memmove(dstmem, srcmem, len);
		}

		return len;
	} else if (!src_is_fd) {
		return fuse_buf_write(dst, dst_off, src, src_off, len);
	} else if (!dst_is_fd) {
		return fuse_buf_read(dst, dst_off, src, src_off, len);
	} else if (flags & FUSE_BUF_NO_SPLICE) {
		return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
	} else {
		return fuse_buf_splice(dst, dst_off, src, src_off, len, flags);
	}
}

static const struct fuse_buf *fuse_bufvec_current(struct fuse_bufvec *bufv)
{
	if (bufv->idx < bufv->count)
		return &bufv->buf[bufv->idx];
	else
		return NULL;
}

static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
{
	const struct fuse_buf *buf = fuse_bufvec_current(bufv);

	bufv->off += len;
	assert(bufv->off <= buf->size);
	if (bufv->off == buf->size) {
		assert(bufv->idx < bufv->count);
		bufv->idx++;
		if (bufv->idx == bufv->count)
			return 0;
		bufv->off = 0;
	}
	return 1;
}

ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv,
		      enum fuse_buf_copy_flags flags)
{
	size_t copied = 0;

	if (dstv == srcv)
		return fuse_buf_size(dstv);

	for (;;) {
		const struct fuse_buf *src = fuse_bufvec_current(srcv);
		const struct fuse_buf *dst = fuse_bufvec_current(dstv);
		size_t src_len;
		size_t dst_len;
		size_t len;
		ssize_t res;

		if (src == NULL || dst == NULL)
			break;

		src_len = src->size - srcv->off;
		dst_len = dst->size - dstv->off;
		len = min_size(src_len, dst_len);

		res = fuse_buf_copy_one(dst, dstv->off, src, srcv->off, len, flags);
		if (res < 0) {
			if (!copied)
				return res;
			break;
		}
		copied += res;

		if (!fuse_bufvec_advance(srcv, res) ||
		    !fuse_bufvec_advance(dstv, res))
			break;

		if (res < len)
			break;
	}

	return copied;
}
