/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <attr/xattr.h>
#include <fcntl.h>
#include <unistd.h>

#include "ctree.h"
#include "commands.h"
#include "utils.h"
#include "props.h"

#define XATTR_BTRFS_PREFIX     "btrfs."
#define XATTR_BTRFS_PREFIX_LEN (sizeof(XATTR_BTRFS_PREFIX) - 1)


static int prop_read_only(enum prop_object_type type,
			  const char *object,
			  const char *name,
			  const char *value)
{
	int ret = 0;
	int fd = -1;
	u64 flags = 0;

	fd = open(object, O_RDONLY);
	if (fd < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: open %s failed. %s\n",
				object, strerror(-ret));
		goto out;
	}

	ret = ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags);
	if (ret < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: failed to get flags for %s. %s\n",
				object, strerror(-ret));
		goto out;
	}

	if (!value) {
		if (flags & BTRFS_SUBVOL_RDONLY)
			fprintf(stdout, "ro=true\n");
		else
			fprintf(stdout, "ro=false\n");
		ret = 0;
		goto out;
	}

	if (!strcmp(value, "true")) {
		flags |= BTRFS_SUBVOL_RDONLY;
	} else if (!strcmp(value, "false")) {
		flags = flags & ~BTRFS_SUBVOL_RDONLY;
	} else {
		ret = -EINVAL;
		fprintf(stderr, "ERROR: invalid value for property.\n");
		goto out;
	}

	ret = ioctl(fd, BTRFS_IOC_SUBVOL_SETFLAGS, &flags);
	if (ret < 0) {
		ret = -errno;
		fprintf(stderr, "ERROR: failed to set flags for %s. %s\n",
				object, strerror(-ret));
		goto out;
	}

out:
	if (fd != -1)
		close(fd);
	return ret;
}

static int prop_label(enum prop_object_type type,
		      const char *object,
		      const char *name,
		      const char *value)
{
	int ret;

	if (value) {
		ret = set_label((char *) object, (char *) value);
	} else {
		char label[BTRFS_LABEL_SIZE];

		ret = get_label((char *) object, label);
		if (!ret)
			fprintf(stdout, "label=%s\n", label);
	}

	return ret;
}

static int prop_compression(enum prop_object_type type,
			    const char *object,
			    const char *name,
			    const char *value)
{
	int ret;
	ssize_t sret;
	int fd = -1;
	DIR *dirstream = NULL;
	char *buf = NULL;
	char *xattr_name = NULL;
	int open_flags = value ? O_RDWR : O_RDONLY;

	fd = open_file_or_dir3(object, &dirstream, open_flags);
	if (fd == -1) {
		ret = -errno;
		fprintf(stderr, "ERROR: open %s failed. %s\n",
			object, strerror(-ret));
		goto out;
	}

	xattr_name = malloc(XATTR_BTRFS_PREFIX_LEN + strlen(name) + 1);
	if (!xattr_name) {
		ret = -ENOMEM;
		goto out;
	}
	memcpy(xattr_name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN);
	memcpy(xattr_name + XATTR_BTRFS_PREFIX_LEN, name, strlen(name));
	xattr_name[XATTR_BTRFS_PREFIX_LEN + strlen(name)] = '\0';

	if (value)
		sret = fsetxattr(fd, xattr_name, value, strlen(value), 0);
	else
		sret = fgetxattr(fd, xattr_name, NULL, 0);
	if (sret < 0) {
		ret = -errno;
		if (ret != -ENOATTR)
			fprintf(stderr,
				"ERROR: failed to %s compression for %s. %s\n",
				value ? "set" : "get", object, strerror(-ret));
		else
			ret = 0;
		goto out;
	}
	if (!value) {
		size_t len = sret;

		buf = malloc(len);
		if (!buf) {
			ret = -ENOMEM;
			goto out;
		}
		sret = fgetxattr(fd, xattr_name, buf, len);
		if (sret < 0) {
			ret = -errno;
			fprintf(stderr,
				"ERROR: failed to get compression for %s. %s\n",
				object, strerror(-ret));
			goto out;
		}
		fprintf(stdout, "compression=%.*s\n", (int)len, buf);
	}

	ret = 0;
out:
	free(xattr_name);
	free(buf);
	if (fd >= 0)
		close_file_or_dir(fd, dirstream);

	return ret;
}


const struct prop_handler prop_handlers[] = {
	{"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol,
	 prop_read_only},
	{"label", "Set/get label of device.", 0,
	 prop_object_dev | prop_object_root, prop_label},
	{"compression", "Set/get compression for a file or directory", 0,
	 prop_object_inode, prop_compression},
	{0, 0, 0, 0, 0}
};
