/*
 * Copyright (C) 2012 Alexander Block.
 * Copyright (C) 2012, 2013 STRATO AG.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <strings.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <uuid/uuid.h>
#include <sys/ioctl.h>
#include <sys/mnttab.h>
#include <libzfs.h>

#include "far-rcv/far-rcv.h"


struct zfs_rcv_ctx {
	struct far_rcv_ctx frctx; /* MUST be the first member */

	libzfs_handle_t *zfs;

	char *base_dataset; /* command line option -b */
	char *cur_dataset; /* current dataset w/o @... */
	char *cur_full_dataset; /* base_dataset + cur_dataset */
	char *cur_snapshot; /* @..., including the @ in the front */

	char *explicit_dest_subvol;
};


static void usage(const char *progname);
int main(int argc, char **argv);
static int zfs_rcv_finish_subvol(struct far_rcv_ctx *frctx);
static int zfs_rcv_process_subvol(struct far_rcv_ctx *frctx, const char *path,
				  const unsigned char *uuid,
				  uint64_t ctransid);
static int zfs_rcv_process_snapshot(struct far_rcv_ctx *frctx,
				    const char *path,
				    const unsigned char *uuid,
				    uint64_t ctransid,
				    const unsigned char *parent_uuid,
				    uint64_t parent_ctransid);
static int zfs_rcv_process_subvol_snapshot(struct far_rcv_ctx *frctx,
					   const char *path, int is_snapshot);


static void usage(const char *progname)
{
	fprintf(stderr, "%s [-ve] [-f <infile>] [-d <dest>] <dataset_base>\n",
		progname);
	char *more[] = {
"Receive snapshots from stdin.",
"Receives one or more snapshots that were previously sent with btrfs send,",
"zfs send -F or a similar sender for the FAR stream format.",
"ZFS filesystems are created and mounted as required. The received data is",
"stored below the ZFS pool or dataset <dataset_base>.",
"-v            Enable verbose debug output. Each occurrency of this option",
"              increases the verbose level more.",
"-e            Terminate after receiving an <end cmd> in the data stream.",
"              Without this option, the receiver terminates only if an error",
"              is recognized or on EOF.",
"-f <infile>   By default, stdin is used to receive the subvolumes. Use this",
"              option to specify a file to use instead.",
"-d <dest>     With <dest> either being filesystem@snapshot or only the name",
"              of a filesystem, this option overrides the name of received",
"              filesystems and optionally also the name of the first received",
"              snapshot.",
NULL
	};
	char **pp = more;

	while (*pp) {
		fprintf(stderr, "%s\n", *pp);
		pp++;
	}
}

int main(int argc, char **argv)
{
	int c;
	char *fromfile = NULL;
	int stream_fd = -1;
	int ret = 0;
	int verbose = 0;
	const char *progname;
	int did_far_rcv_init = 0;
	struct zfs_rcv_ctx *zrctx = NULL;
	int support_xattrs = 1;
	int honor_end_cmd = 0;

	progname = basename(argv[0]);
	zrctx = calloc(1, sizeof(*zrctx));
	if (!zrctx) {
		ret = -ENOMEM;
		fprintf(stderr, "%s: ERROR: malloc() failed.\n", progname);
		goto out;
	}

	zrctx->zfs = NULL;
	zrctx->base_dataset = NULL;
	zrctx->cur_dataset = NULL;
	zrctx->cur_full_dataset = NULL;
	zrctx->cur_snapshot = NULL;
	zrctx->explicit_dest_subvol = NULL;

	while ((c = getopt(argc, argv, "vexXsSf:d:")) != -1) {
		switch (c) {
		case 'v':
			verbose++;
			break;
		case 'e':
			honor_end_cmd = 1;
			break;
		case 'x':
			support_xattrs = 0;
			break;
		case 'X':
			support_xattrs = 1;
			break;
		case 's':
		case 'S':
			/* ignored */
			break;
		case 'f':
			fromfile = optarg;
			break;
		case 'd':
			zrctx->explicit_dest_subvol = optarg;
			break;
		case '?':
		default:
			fprintf(stderr, "%s: ERROR: args invalid.\n", progname);
			usage(progname);
			ret = -EINVAL;
			goto out;
		}
	}

	if (optind + 1 < argc) {
		ret = -EINVAL;
		fprintf(stderr, "%s: ERROR: too many arguments.\n", progname);
		usage(progname);
		goto out;
	} else if (optind + 1 != argc) {
		ret = -EINVAL;
		fprintf(stderr, "%s: ERROR: need <dataset_base>.\n", progname);
		usage(progname);
		goto out;
	}
	zrctx->base_dataset = argv[optind];

	if (fromfile) {
		stream_fd = open(fromfile, O_RDONLY);
		if (stream_fd < 0) {
			ret = -errno;
			fprintf(stderr,
				"%s: ERROR: failed to open \"%s\". %s.\n",
				progname, fromfile, strerror(errno));
			goto out;
		}
	} else {
		stream_fd = 0; /* stdin */
	}

	zrctx->zfs = libzfs_init();

	did_far_rcv_init = 1;
	ret = far_rcv_init(&zrctx->frctx);
	if (ret) {
		fprintf(stderr, "%s: ERROR: far_rcv_init() failed. %s.\n",
			progname, strerror(-ret));
		goto out;
	}

	zrctx->frctx.verbose = verbose;
	zrctx->frctx.support_xattrs = support_xattrs;
	zrctx->frctx.honor_end_cmd = honor_end_cmd;
	zrctx->frctx.ops.finish_subvol = zfs_rcv_finish_subvol;
	zrctx->frctx.ops.subvol = zfs_rcv_process_subvol;
	zrctx->frctx.ops.snapshot = zfs_rcv_process_snapshot;

	ret = far_rcv_mainloop(&zrctx->frctx, stream_fd, "./");
	if (ret) {
		fprintf(stderr,
			"%s: ERROR, far_rcv_mainloop() failed with %s.\n",
			progname, strerror(-ret));
		goto out;
	}

out:
	if (did_far_rcv_init)
		far_rcv_deinit(&zrctx->frctx);
	if (stream_fd >= 0)
		close(stream_fd);
	if (zrctx) {
		free(zrctx->cur_dataset);
		free(zrctx->cur_full_dataset);
		free(zrctx->cur_snapshot);
	}
	if (zrctx->zfs)
		libzfs_fini(zrctx->zfs);
	free(zrctx);
	exit(-ret);
}

static int zfs_rcv_finish_subvol(struct far_rcv_ctx *frctx)
{
	struct zfs_rcv_ctx *zrctx = (struct zfs_rcv_ctx *)frctx;
	int ret = 0;

	if (zrctx->cur_dataset == NULL)
		return 0;

	if (zrctx->cur_snapshot) {
		int l1 = strlen(zrctx->cur_full_dataset);
		int l2 = strlen(zrctx->cur_snapshot);
		char *path = malloc(l1 + l2 + 1);

		strcpy(path, zrctx->cur_full_dataset);
		strcat(path, zrctx->cur_snapshot);
		ret = zfs_snapshot(zrctx->zfs, path, 1, NULL);
		free(zrctx->cur_snapshot);
		zrctx->cur_snapshot = NULL;
	}

	free(zrctx->cur_dataset);
	zrctx->cur_dataset = NULL;
	free(zrctx->cur_full_dataset);
	zrctx->cur_full_dataset = NULL;

	return ret;
}

static int zfs_rcv_process_subvol(struct far_rcv_ctx *frctx, const char *path,
				  const unsigned char *uuid, uint64_t ctransid)
{
	return zfs_rcv_process_subvol_snapshot(frctx, path, 0);
}

static int zfs_rcv_process_snapshot(struct far_rcv_ctx *frctx, const char *path,
				    const unsigned char *uuid,
				    uint64_t ctransid,
				    const unsigned char *parent_uuid,
				    uint64_t parent_ctransid)
{
	return zfs_rcv_process_subvol_snapshot(frctx, path, 1);
}

static int zfs_rcv_process_subvol_snapshot(struct far_rcv_ctx *frctx,
					   const char *path, int is_snapshot)
{
	struct zfs_rcv_ctx *zrctx = (struct zfs_rcv_ctx *)frctx;
	int ret;
	char *p;
	zfs_handle_t *zfh = NULL;
	char *mounted_where = NULL;

	ret = zfs_rcv_finish_subvol(frctx);
	if (ret < 0)
		goto out;

	assert(zrctx->cur_dataset == NULL);
	assert(zrctx->cur_full_dataset == NULL);
	assert(zrctx->cur_snapshot == NULL);
	if (zrctx->explicit_dest_subvol) {
		if (zrctx->frctx.verbose)
			fprintf(stderr, "Override destination, use \"%s\".\n",
				zrctx->explicit_dest_subvol);
		zrctx->cur_dataset = strdup(zrctx->explicit_dest_subvol);
		p = strrchr(zrctx->explicit_dest_subvol, '@');
		/*
		 * use (optional) snapshot name only for the first one,
		 * all following ones take the snapshot name out of the
		 * transmitted name, and use the explicit name only for
		 * the name of the filesystem
		 */
		if (p) {
			*p = '\0';
		} else {
			p = strrchr(path, '@');
			if (p)
				zrctx->cur_snapshot = strdup(p);
		}
	} else {
		zrctx->cur_dataset = strdup(path);
	}

	p = strrchr(zrctx->cur_dataset, '@');
	if (p) {
		zrctx->cur_snapshot = strdup(p);
		*p = '\0';
	}

	if (frctx->free_current_base_path)
		free((void *)frctx->current_base_path);
	frctx->free_current_base_path = 0;

	zrctx->cur_full_dataset = far_rcv_path_cat(zrctx->base_dataset,
						   zrctx->cur_dataset);
	if (is_snapshot) {
		if (zrctx->cur_snapshot)
			fprintf(stderr, "At snapshot %s%s.\n",
				zrctx->cur_dataset, zrctx->cur_snapshot);
		else /* this will leave with an error message later */
			fprintf(stderr, "At snapshot %s.\n",
				zrctx->cur_dataset);

	} else {
		fprintf(stderr, "At subvol %s.\n", zrctx->cur_dataset);
	}

	if (is_snapshot) {
		/*
		 * This means nothing more than that this is an incremental
		 * transfer.
		 * Note that the term "snapshot" in the FAR stream format
		 * stands for incremental transfers while "subvolume" stands
		 * for full transfers. This is not related to ZFS filesystems
		 * and snapshots.
		 *
		 * For incremental transfers, it is enforced that the
		 * target is a snapshot, i.e. that the information is
		 * there which name shall be used for the snapshot.
		 */
		if (!zrctx->cur_snapshot) {
			ret = -EINVAL;
			fprintf(stderr,
				"ERROR: no snapshot name \"@...\" for %s.\n",
				zrctx->cur_dataset);
			goto out;
		}

		/* check that filesystem is existent */
		zfh = zfs_open(zrctx->zfs, zrctx->cur_full_dataset,
			       ZFS_TYPE_FILESYSTEM);
		if (!zfh) {
			ret = -libzfs_errno(zrctx->zfs);
			fprintf(stderr,
				"ERROR: filesystem %s cannot be opened, libzfs_errno = %d, %s.\n",
				zrctx->cur_full_dataset, -ret,
				libzfs_error_description(zrctx->zfs));
			goto out;
		}
	} else {
		ret = zfs_create(zrctx->zfs, zrctx->cur_full_dataset,
				 ZFS_TYPE_FILESYSTEM, NULL);
		if (ret && libzfs_errno(zrctx->zfs) != EZFS_EXISTS) {
			ret = -libzfs_errno(zrctx->zfs);
			fprintf(stderr,
				"ERROR: create filesystem %s fails with libzfs_errno %d, %s.\n",
				zrctx->cur_full_dataset, -ret,
				libzfs_error_description(zrctx->zfs));
			goto out;
		} else if (ret && libzfs_errno(zrctx->zfs) == EZFS_EXISTS) {
			/*
			 * This won't work as expected in most cases unless
			 * the existent filesystem is empty. Enforce that
			 * only incrementally sent data can be applied to
			 * existent filesystems. What should we do otherwise,
			 * remove everything in the filesystem at the
			 * beginning, then apply the received data, than
			 * create a snapshot, afterwards do what?
			 */
			fprintf(stderr,
				"ERROR: filesystem %s already exists, only incrementally sent data is supported!\n",
				zrctx->cur_full_dataset);
			goto out;
		}

		zfh = zfs_open(zrctx->zfs, zrctx->cur_full_dataset,
			       ZFS_TYPE_FILESYSTEM);
		if (!zfh) {
			ret = -libzfs_errno(zrctx->zfs);
			fprintf(stderr,
				"ERROR: filesystem %s cannot be opened, libzfs_errno = %d, %s.\n",
				zrctx->cur_full_dataset, -ret,
				libzfs_error_description(zrctx->zfs));
			goto out;
		}
	}

	/* need to mount filesystem if it not there as expected */
	if (!zfs_is_mounted(zfh, &mounted_where)) {
		ret = zfs_mount(zfh, NULL, 0);
		if (ret) {
			ret = -libzfs_errno(zrctx->zfs);
			fprintf(stderr,
				"ERROR: filesystem %s cannot be mounted, libzfs_errno = %d, %s.\n",
				zrctx->cur_full_dataset, -ret,
				libzfs_error_description(zrctx->zfs));
			goto out;
		}
		if (!zfs_is_mounted(zfh, &mounted_where)) {
			fprintf(stderr,
				"ERROR: failed to mount filesystem %s.\n",
				zrctx->cur_full_dataset);
			ret = EZFS_MOUNTFAILED;
			goto out;
		}
	}

	frctx->current_base_path = mounted_where;
	mounted_where = NULL;
	frctx->free_current_base_path = 1;

out:
	free(mounted_where);
	if (zfh != NULL)
		zfs_close(zfh);
	return ret;
}
