/*
 * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "lib.h"
#include "label.h"
#include "metadata.h"
#include "lvmcache.h"
#include "xlate.h"
#include "disk_rep.h"
#include "toolcontext.h"

#include <assert.h>

/* FIXME: memcpy might not be portable */
#define CPIN_8(x, y, z) {memcpy((x), (y), (z));}
#define CPOUT_8(x, y, z) {memcpy((y), (x), (z));}
#define CPIN_16(x, y) {(x) = xlate16_be((y));}
#define CPOUT_16(x, y) {(y) = xlate16_be((x));}
#define CPIN_32(x, y) {(x) = xlate32_be((y));}
#define CPOUT_32(x, y) {(y) = xlate32_be((x));}
#define CPIN_64(x, y) {(x) = xlate64_be((y));}
#define CPOUT_64(x, y) {(y) = xlate64_be((x));}

static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
			    struct dm_pool *mem __attribute__((unused)), struct pool_list *pl,
			    const char *vg_name __attribute__((unused)))
{
	char buf[512] __attribute__((aligned(8)));

	/* FIXME: Need to check the cache here first */
	if (!dev_read(dev, UINT64_C(0), 512, buf)) {
		log_very_verbose("Failed to read PV data from %s",
				 dev_name(dev));
		return 0;
	}

	if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL))
		return_0;

	return 1;
}

static void _add_pl_to_list(struct cmd_context *cmd, struct dm_list *head, struct pool_list *data)
{
	struct pool_list *pl;

	dm_list_iterate_items(pl, head) {
		if (id_equal(&data->pv_uuid, &pl->pv_uuid)) {
			char uuid[ID_LEN + 7] __attribute__((aligned(8)));

			if (!id_write_format(&pl->pv_uuid, uuid, ID_LEN + 7))
				stack;

			if (!dev_subsystem_part_major(cmd->dev_types, data->dev)) {
				log_very_verbose("Ignoring duplicate PV %s on "
						 "%s", uuid,
						 dev_name(data->dev));
				return;
			}
			log_very_verbose("Duplicate PV %s - using %s %s",
					 uuid, dev_subsystem_name(cmd->dev_types, data->dev),
					 dev_name(data->dev));
			dm_list_del(&pl->list);
			break;
		}
	}
	dm_list_add(head, &data->list);
}

int read_pool_label(struct pool_list *pl, struct labeller *l,
		    struct device *dev, char *buf, struct label **label)
{
	struct lvmcache_info *info;
	struct id pvid;
	struct id vgid;
	char uuid[ID_LEN + 7] __attribute__((aligned(8)));
	struct pool_disk *pd = &pl->pd;

	pool_label_in(pd, buf);

	get_pool_pv_uuid(&pvid, pd);
	if (!id_write_format(&pvid, uuid, ID_LEN + 7))
		stack;
	log_debug_metadata("Calculated uuid %s for %s", uuid, dev_name(dev));

	get_pool_vg_uuid(&vgid, pd);
	if (!id_write_format(&vgid, uuid, ID_LEN + 7))
		stack;
	log_debug_metadata("Calculated uuid %s for %s", uuid, pd->pl_pool_name);

	if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name,
				  (char *) &vgid, 0)))
		return_0;
	if (label)
		*label = lvmcache_get_label(info);

	lvmcache_set_device_size(info, ((uint64_t)xlate32_be(pd->pl_blocks)) << SECTOR_SHIFT);
	lvmcache_set_ext_version(info, 0);
	lvmcache_set_ext_flags(info, 0);
	lvmcache_del_mdas(info);
	lvmcache_del_bas(info);
	lvmcache_make_valid(info);

	pl->dev = dev;
	pl->pv = NULL;
	memcpy(&pl->pv_uuid, &pvid, sizeof(pvid));

	return 1;
}

/**
 * pool_label_out - copies a pool_label_t into a char buffer
 * @pl: ptr to a pool_label_t struct
 * @buf: ptr to raw space where label info will be copied
 *
 * This function is important because it takes care of all of
 * the endian issues when copying to disk.  This way, when
 * machines of different architectures are used, they will
 * be able to interpret ondisk labels correctly.  Always use
 * this function before writing to disk.
 */
void pool_label_out(struct pool_disk *pl, void *buf)
{
	struct pool_disk *bufpl = (struct pool_disk *) buf;

	CPOUT_64(pl->pl_magic, bufpl->pl_magic);
	CPOUT_64(pl->pl_pool_id, bufpl->pl_pool_id);
	CPOUT_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE);
	CPOUT_32(pl->pl_version, bufpl->pl_version);
	CPOUT_32(pl->pl_subpools, bufpl->pl_subpools);
	CPOUT_32(pl->pl_sp_id, bufpl->pl_sp_id);
	CPOUT_32(pl->pl_sp_devs, bufpl->pl_sp_devs);
	CPOUT_32(pl->pl_sp_devid, bufpl->pl_sp_devid);
	CPOUT_32(pl->pl_sp_type, bufpl->pl_sp_type);
	CPOUT_64(pl->pl_blocks, bufpl->pl_blocks);
	CPOUT_32(pl->pl_striping, bufpl->pl_striping);
	CPOUT_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs);
	CPOUT_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid);
	CPOUT_32(pl->pl_sp_weight, bufpl->pl_sp_weight);
	CPOUT_32(pl->pl_minor, bufpl->pl_minor);
	CPOUT_32(pl->pl_padding, bufpl->pl_padding);
	CPOUT_8(pl->pl_reserve, bufpl->pl_reserve, 184);
}

/**
 * pool_label_in - copies a char buffer into a pool_label_t
 * @pl: ptr to a pool_label_t struct
 * @buf: ptr to raw space where label info is copied from
 *
 * This function is important because it takes care of all of
 * the endian issues when information from disk is about to be
 * used.  This way, when machines of different architectures
 * are used, they will be able to interpret ondisk labels
 * correctly.  Always use this function before using labels that
 * were read from disk.
 */
void pool_label_in(struct pool_disk *pl, void *buf)
{
	struct pool_disk *bufpl = (struct pool_disk *) buf;

	CPIN_64(pl->pl_magic, bufpl->pl_magic);
	CPIN_64(pl->pl_pool_id, bufpl->pl_pool_id);
	CPIN_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE);
	CPIN_32(pl->pl_version, bufpl->pl_version);
	CPIN_32(pl->pl_subpools, bufpl->pl_subpools);
	CPIN_32(pl->pl_sp_id, bufpl->pl_sp_id);
	CPIN_32(pl->pl_sp_devs, bufpl->pl_sp_devs);
	CPIN_32(pl->pl_sp_devid, bufpl->pl_sp_devid);
	CPIN_32(pl->pl_sp_type, bufpl->pl_sp_type);
	CPIN_64(pl->pl_blocks, bufpl->pl_blocks);
	CPIN_32(pl->pl_striping, bufpl->pl_striping);
	CPIN_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs);
	CPIN_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid);
	CPIN_32(pl->pl_sp_weight, bufpl->pl_sp_weight);
	CPIN_32(pl->pl_minor, bufpl->pl_minor);
	CPIN_32(pl->pl_padding, bufpl->pl_padding);
	CPIN_8(pl->pl_reserve, bufpl->pl_reserve, 184);
}

static char _calc_char(unsigned int id)
{
	/*
	 * [0-9A-Za-z!#] - 64 printable chars (6-bits)
	 */

	if (id < 10)
		return id + 48;
	if (id < 36)
		return (id - 10) + 65;
	if (id < 62)
		return (id - 36) + 97;
	if (id == 62)
		return '!';
	if (id == 63)
		return '#';

	return '%';
}

void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid)
{
	int i;
	unsigned shifter = 0x003F;

	assert(ID_LEN == 32);
	memset(uuid, 0, ID_LEN);
	strcat(uuid, "POOL0000000000");

	/* We grab the entire 64 bits (+2 that get shifted in) */
	for (i = 13; i < 24; i++) {
		uuid[i] = _calc_char(((unsigned) poolid) & shifter);
		poolid = poolid >> 6;
	}

	/* We grab the entire 32 bits (+4 that get shifted in) */
	for (i = 24; i < 30; i++) {
		uuid[i] = _calc_char((unsigned) (spid & shifter));
		spid = spid >> 6;
	}

	/*
	 * Since we can only have 128 devices, we only worry about the
	 * last 12 bits
	 */
	for (i = 30; i < 32; i++) {
		uuid[i] = _calc_char((unsigned) (devid & shifter));
		devid = devid >> 6;
	}

}

struct _read_pool_pv_baton {
	const struct format_type *fmt;
	struct dm_pool *mem, *tmpmem;
	struct pool_list *pl;
	struct dm_list *head;
	const char *vgname;
	uint32_t *sp_devs;
	uint32_t sp_count;
	int failed;
	int empty;
};

static int _read_pool_pv(struct lvmcache_info *info, void *baton)
{
	struct _read_pool_pv_baton *b = baton;

	b->empty = 0;

	if (lvmcache_device(info) &&
	    !(b->pl = read_pool_disk(b->fmt, lvmcache_device(info), b->mem, b->vgname)))
		return 0;

	/*
	 * We need to keep track of the total expected number
	 * of devices per subpool
	 */
	if (!b->sp_count) {
		/* FIXME pl left uninitialised if !info->dev */
		if (!b->pl) {
			log_error(INTERNAL_ERROR "device is missing");
			dm_pool_destroy(b->tmpmem);
			b->failed = 1;
			return 0;
		}
		b->sp_count = b->pl->pd.pl_subpools;
		if (!(b->sp_devs =
		      dm_pool_zalloc(b->tmpmem,
				     sizeof(uint32_t) * b->sp_count))) {
			log_error("Unable to allocate %d 32-bit uints",
				  b->sp_count);
			dm_pool_destroy(b->tmpmem);
			b->failed = 1;
			return 0;
		}
	}

	/*
	 * watch out for a pool label with a different subpool
	 * count than the original - give up if it does
	 */
	if (b->sp_count != b->pl->pd.pl_subpools)
		return 0;

	_add_pl_to_list(lvmcache_fmt(info)->cmd, b->head, b->pl);

	if (b->sp_count > b->pl->pd.pl_sp_id && b->sp_devs[b->pl->pd.pl_sp_id] == 0)
		b->sp_devs[b->pl->pd.pl_sp_id] = b->pl->pd.pl_sp_devs;

	return 1;
}

static int _read_vg_pds(struct _read_pool_pv_baton *b,
			struct lvmcache_vginfo *vginfo,
			uint32_t *devcount)
{
	uint32_t i;

	b->sp_count = 0;
	b->sp_devs = NULL;
	b->failed = 0;
	b->pl = NULL;

	/* FIXME: maybe should return a different error in memory
	 * allocation failure */
	if (!(b->tmpmem = dm_pool_create("pool read_vg", 512)))
		return_0;

	lvmcache_foreach_pv(vginfo, _read_pool_pv, b);

	*devcount = 0;
	for (i = 0; i < b->sp_count; i++)
		*devcount += b->sp_devs[i];

	dm_pool_destroy(b->tmpmem);

	if (b->pl && *b->pl->pd.pl_pool_name)
		return 1;

	return 0;

}

int read_pool_pds(const struct format_type *fmt, const char *vg_name,
		  struct dm_pool *mem, struct dm_list *pdhead)
{
	struct lvmcache_vginfo *vginfo;
	uint32_t totaldevs;
	int full_scan = -1;

	struct _read_pool_pv_baton baton;

	baton.vgname = vg_name;
	baton.mem = mem;
	baton.fmt = fmt;
	baton.head = pdhead;
	baton.empty = 1;

	do {
		/*
		 * If the cache scanning doesn't work, this will never work
		 */
		if (vg_name && (vginfo = lvmcache_vginfo_from_vgname(vg_name, NULL)) &&
		    _read_vg_pds(&baton, vginfo, &totaldevs) && !baton.empty)
		{
			/*
			 * If we found all the devices we were expecting, return
			 * success
			 */
			if (dm_list_size(pdhead) == totaldevs)
				return 1;

			/*
			 * accept partial pool if we've done a full rescan of
			 * the cache
			 */
			if (full_scan > 0)
				return 1;
		}

		/* Failed */
		dm_list_init(pdhead);

		full_scan++;
		if (full_scan > 1) {
			log_debug_metadata("No devices for vg %s found in cache",
					   vg_name);
			return 0;
		}
		if (full_scan > 0)
			lvmcache_force_next_label_scan();
		lvmcache_label_scan(fmt->cmd);

	} while (1);

}

struct pool_list *read_pool_disk(const struct format_type *fmt,
				 struct device *dev, struct dm_pool *mem,
				 const char *vg_name)
{
	struct pool_list *pl;

	if (!dev_open_readonly(dev))
		return_NULL;

	if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
		log_error("Unable to allocate pool list structure");
		return 0;
	}

	if (!__read_pool_disk(fmt, dev, mem, pl, vg_name))
		return_NULL;

	if (!dev_close(dev))
		stack;

	return pl;

}
