#include "c.h"
#include "strutils.h"

#ifdef HAVE_LIBBLKID
# include <blkid.h>
#endif

#include "fdiskP.h"

struct fdisk_wipe {
	struct list_head	wipes;
	uint64_t		start;		/* sectors */
	uint64_t		size;		/* sectors */
};

static struct fdisk_wipe *fdisk_get_wipe_area(
			struct fdisk_context *cxt,
			uint64_t start,
			uint64_t size)
{
	struct list_head *p;

	if (cxt == NULL || list_empty(&cxt->wipes))
		return NULL;

	list_for_each(p, &cxt->wipes) {
		struct fdisk_wipe *wp = list_entry(p, struct fdisk_wipe, wipes);
		if (wp->start == start && wp->size == size)
			return wp;
	}
	return NULL;
}

void fdisk_free_wipe_areas(struct fdisk_context *cxt)
{
	while (!list_empty(&cxt->wipes)) {
		struct fdisk_wipe *wp = list_entry(cxt->wipes.next,
				                  struct fdisk_wipe, wipes);
		DBG(WIPE, ul_debugobj(wp, "free [start=%ju, size=%ju]",
				(uintmax_t) wp->start, (uintmax_t) wp->size));
		list_del(&wp->wipes);
		free(wp);
	}
}

int fdisk_has_wipe_area(struct fdisk_context *cxt,
			uint64_t start,
			uint64_t size)
{
	return fdisk_get_wipe_area(cxt, start, size) != NULL;
}

/* Add/remove new wiping area
 *
 * Returns: <0 on error, or old area setting (1: enabled, 0: disabled)
 */
int fdisk_set_wipe_area(struct fdisk_context *cxt,
			uint64_t start,
			uint64_t size,
			int enable)
{
	struct fdisk_wipe *wp;

	if (FDISK_IS_UNDEF(start) || FDISK_IS_UNDEF(size))
		return -EINVAL;

	wp = fdisk_get_wipe_area(cxt, start, size);

	/* disable */
	if (!enable) {
		if (wp) {
			DBG(WIPE, ul_debugobj(wp, "disable [start=%ju, size=%ju]",
						(uintmax_t) start, (uintmax_t) size));
			list_del(&wp->wipes);
			free(wp);
			return 1;
		}
		return 0;
	}

	/* enable */
	if (wp)
		return 1;	/* already enabled */

	wp = calloc(1, sizeof(*wp));
	if (!wp)
		return -ENOMEM;

	DBG(WIPE, ul_debugobj(wp, "enable [start=%ju, size=%ju]",
				(uintmax_t) start, (uintmax_t) size));

	INIT_LIST_HEAD(&wp->wipes);
	wp->start = start;
	wp->size = size;
	list_add_tail(&wp->wipes, &cxt->wipes);

	return 0;
}

#ifndef HAVE_LIBBLKID
int fdisk_do_wipe(struct fdisk_context *cxt __attribute__((__unused__)))
{
	return 0;
}
#else
int fdisk_do_wipe(struct fdisk_context *cxt)
{
	struct list_head *p;
	blkid_probe pr;
	int rc;

	assert(cxt);
	assert(cxt->dev_fd >= 0);

	if (list_empty(&cxt->wipes))
		return 0;

	pr = blkid_new_probe();
	if (!pr)
		return -ENOMEM;

	list_for_each(p, &cxt->wipes) {
		struct fdisk_wipe *wp = list_entry(p, struct fdisk_wipe, wipes);
		blkid_loff_t start = (blkid_loff_t) wp->start * cxt->sector_size,
			     size = (blkid_loff_t) wp->size * cxt->sector_size;

		DBG(WIPE, ul_debugobj(wp, "initialize libblkid prober [start=%ju, size=%ju]",
                                            (uintmax_t) start, (uintmax_t) size));

		rc = blkid_probe_set_device(pr, cxt->dev_fd, start, size);
		if (rc) {
			DBG(WIPE, ul_debugobj(wp, "blkid_probe_set_device() failed [rc=%d]", rc));
			return rc;
		}

		blkid_probe_enable_superblocks(pr, 1);
		blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
		blkid_probe_enable_partitions(pr, 1);
		blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);

		while (blkid_do_probe(pr) == 0) {
			DBG(WIPE, ul_debugobj(wp, " wiping..."));
			blkid_do_wipe(pr, FALSE);
		}
	}

	blkid_free_probe(pr);
	return 0;
}
#endif


/*
 * Please don't call this function if there is already a PT.
 *
 * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
 */
#ifndef HAVE_LIBBLKID
int fdisk_check_collisions(struct fdisk_context *cxt __attribute__((__unused__)))
{
	return 0;
}
#else
int fdisk_check_collisions(struct fdisk_context *cxt)
{
	int rc = 0;
	blkid_probe pr;

	assert(cxt);
	assert(cxt->dev_fd >= 0);

	DBG(CXT, ul_debugobj(cxt, "wipe check: initialize libblkid prober"));

	pr = blkid_new_probe();
	if (!pr)
		return -ENOMEM;
	rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
	if (rc)
		return rc;

	cxt->pt_collision = 0;
	free(cxt->collision);
	cxt->collision = NULL;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
	blkid_probe_enable_partitions(pr, 1);

	/* we care about the first found FS/raid, so don't call blkid_do_probe()
	 * in loop or don't use blkid_do_fullprobe() ... */
	rc = blkid_do_probe(pr);
	if (rc == 0) {
		const char *name = NULL;

		if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0)
			cxt->collision = strdup(name);
		else if (blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
			cxt->collision = strdup(name);
			cxt->pt_collision = 1;
		}

		if (name && !cxt->collision)
			rc = -ENOMEM;
	}

	blkid_free_probe(pr);
	return rc;
}
#endif
