
#include <inttypes.h>

#include "fdiskP.h"

/**
 * SECTION: item
 * @title: Labelitem
 * @short_description: disk label items
 *
 * The labelitem is label specific items stored in the partition table header.
 * The information provided by labelitems are not specific to the partitions.
 *
 * For example
 *
 * <informalexample>
 *  <programlisting>
 *	struct fdisk_labelitem *item = fdisk_new_labelitem();
 *
 *	fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ALTLBA, item);
 *	print("Backup header LBA: %ju\n", fdisk_labelitem_get_data_u64(item));
 *
 *	fdisk_unref_labelitem(item);
 *  </programlisting>
 * </informalexample>
 *
 * returns LBA of the alternative GPT header.
 *
 * See also fdisk_get_disklabel_item(). The IDs are generic (e.g.
 * FDISK_LABEL_ITEM_*) and label specific ((e.g. GPT_LABELITEM_*).
 */

/**
 * fdisk_new_labelitem
 *
 * Returns: new instance.
 * Since: 2.29
 */
struct fdisk_labelitem *fdisk_new_labelitem(void)
{
	struct fdisk_labelitem *li = calloc(1, sizeof(*li));

	li->refcount = 1;
	DBG(ITEM, ul_debugobj(li, "alloc"));
	return li;
}

/**
 * fdisk_ref_labelitem:
 * @li: label item
 *
 * Increments reference counter.
 * Since: 2.29
 */
void fdisk_ref_labelitem(struct fdisk_labelitem *li)
{
	if (li) {
		/* me sure we do not use refcouting for static items */
		assert(li->refcount > 0);
		li->refcount++;
	}
}

/**
 * fdisk_reset_labelitem:
 * @li: label item
 *
 * Zeroize data stored in the @li (does not modify anything in disk label).
 *
 * Returns: 0 on success, or <0 in case of error
 * Since: 2.29
 */
int fdisk_reset_labelitem(struct fdisk_labelitem *li)
{
	int refcount;

	if (!li)
		return -EINVAL;
	if (li->type == 's')
		free(li->data.str);

	refcount = li->refcount;
	memset(li, 0, sizeof(*li));
	li->refcount = refcount;
	return 0;
}

/**
 * fdisk_unref_labelitem:
 * @li: label item
 *
 * Decrements reference counter, on zero the @li is automatically
 * deallocated.
 *
 * Since: 2.29
 */
void fdisk_unref_labelitem(struct fdisk_labelitem *li)
{
	if (!li)
		return;

	/* me sure we do not use refcouting for static items */
	assert(li->refcount > 0);

	li->refcount--;
	if (li->refcount <= 0) {
		DBG(ITEM, ul_debugobj(li, "free"));
		fdisk_reset_labelitem(li);
		free(li);
	}
}

/**
 * fdisk_labelitem_get_name:
 * @li: label item
 *
 * Returns: item name or NULL.
 * Since: 2.29
 */
const char *fdisk_labelitem_get_name(struct fdisk_labelitem *li)
{
	return li ? li->name : NULL;
}

/**
 * fdisk_labelitem_get_id:
 * @li: label item
 *
 * Returns: item Id or <0 in case of error.
 * Since: 2.29
 */
int fdisk_labelitem_get_id(struct fdisk_labelitem *li)
{
	return li ? li->id : -EINVAL;
}


/**
 * fdisk_labelitem_get_data_u64:
 * @li: label item
 * @data: returns data
 *
 * Returns: 0 on success, <0 on error
 * Since: 2.29
 */
int fdisk_labelitem_get_data_u64(struct fdisk_labelitem *li, uint64_t *data)
{
	if (!li || li->type != 'j')
		return -EINVAL;

	if (data)
		*data = li->data.num64;
	return 0;
}

/**
 * fdisk_labelitem_get_data_string:
 * @li: label item
 * @data: returns data
 *
 * Returns: 0 on success, <0 on error.
 * Since: 2.29
 */
int fdisk_labelitem_get_data_string(struct fdisk_labelitem *li, const char **data)
{
	if (!li || li->type != 's')
		return -EINVAL;

	if (data)
		*data = li->data.str;
	return 0;
}

/**
 * fdisk_labelitem_is_string:
 * @li: label item
 *
 * Returns: 0 or 1
 * Since: 2.29
 */
int fdisk_labelitem_is_string(struct fdisk_labelitem *li)
{
	return li && li->type == 's';
}

/**
 * fdisk_labelitem_is_number:
 * @li: label item
 *
 * Returns: 0 or 1
 * Since: 2.29
 */
int fdisk_labelitem_is_number(struct fdisk_labelitem *li)
{
	return li && li->type == 'j';
}

#ifdef TEST_PROGRAM
static int test_listitems(struct fdisk_test *ts, int argc, char *argv[])
{
	const char *disk = argv[1];
	struct fdisk_context *cxt;
	struct fdisk_labelitem *item;
	int i = 0, rc;

	cxt = fdisk_new_context();
	item = fdisk_new_labelitem();

	fdisk_assign_device(cxt, disk, 1);

	do {
		rc = fdisk_get_disklabel_item(cxt, i++, item);
		switch (rc) {
		case 0:	/* success */
		{
			const char *name = fdisk_labelitem_get_name(item);
			const char *str;
			uint64_t num;

			if (fdisk_labelitem_is_string(item)
			    && fdisk_labelitem_get_data_string(item, &str) == 0)
				printf("%s: %s\n", name, str);
			else if (fdisk_labelitem_get_data_u64(item, &num) == 0)
				printf("%s: %"PRIu64"\n", name, num);
			break;
		}
		case 1: /* item unsupported by label -- ignore */
			rc = 0;
			break;
		case 2:	/* end (out of range) */
			break;
		default: /* error */
			break;
		}
	} while (rc == 0);

	fdisk_unref_labelitem(item);
	fdisk_unref_context(cxt);
	return rc < 0 ? rc : 0;
}

int main(int argc, char *argv[])
{
	struct fdisk_test tss[] = {
		{ "--list-items",  test_listitems,  "<disk>             list items" },
		{ NULL }
	};

	return fdisk_run_test(tss, argc, argv);
}

#endif
