/*
 * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 *
 * Libfdisk sample to create partitions by specify size, for example:
 *
 *	mkpart --label dos --device /dev/sdc 2M 2M 2M 10M 1M -
 *
  * creates 6 partitions:
  *	- 3 primary  (3x 2M)
  *	- 1 extended (1x 10M)
  *	- 2 logical  (1x 1M, 1x remaining-space-in-extended-partition)
  *
  * Notes:
  *     The sample specifies size and partno for MBR, and size only for another
  *     labels (e.g. GPT).
  *
  *     The Ask-API does not use anything else than warning/info. The
  *     partitionning has to be done non-interactive.
  */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <getopt.h>

#include "c.h"
#include "nls.h"
#include "strutils.h"
#include "xalloc.h"

#include "libfdisk.h"

static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
			struct fdisk_ask *ask,
			void *data)
{
	switch(fdisk_ask_get_type(ask)) {
	case FDISK_ASKTYPE_INFO:
		fputs(fdisk_ask_print_get_mesg(ask), stdout);
		fputc('\n', stdout);
		break;
	case FDISK_ASKTYPE_WARNX:
		fflush(stdout);
		fputs(fdisk_ask_print_get_mesg(ask), stderr);
		fputc('\n', stderr);
		break;
	case FDISK_ASKTYPE_WARN:
		fflush(stdout);
		fputs(fdisk_ask_print_get_mesg(ask), stderr);
		errno = fdisk_ask_print_get_errno(ask);
		fprintf(stderr, ": %m\n");
		break;
	default:
		break;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	struct fdisk_context *cxt;
	struct fdisk_partition *pa;
	const char *label = NULL, *device = NULL;
	int n = 0, c, nopartno = 0;
	unsigned int sectorsize;
	uint64_t grain = 0;

	static const struct option longopts[] = {
		{ "label",  required_argument, NULL, 'x' },
		{ "device", required_argument, NULL, 'd' },
		{ "nopartno", no_argument, NULL, 'p' },
		{ "grain", required_argument, NULL, 'g' },
		{ "help",   no_argument, NULL, 'h' },
		{ NULL, 0, NULL, 0 },
	};

	setlocale(LC_ALL, "");	/* just to have enable UTF8 chars */

	fdisk_init_debug(0);

	while((c = getopt_long(argc, argv, "g:x:d:h", longopts, NULL)) != -1) {
		switch(c) {
		case 'x':
			label = optarg;
			break;
		case 'd':
			device = optarg;
			break;
		case 'p':
			nopartno = 1;
			break;
		case 'g':
			grain = strtosize_or_err(optarg, "failed to parse grain");
			break;
		case 'h':
			printf("%s [options] <size> ...", program_invocation_short_name);
			fputs(USAGE_SEPARATOR, stdout);
			fputs("Make disklabel and partitions.\n", stdout);
			fputs(USAGE_OPTIONS, stdout);
			fputs(" -x, --label <dos,gpt,...>    disk label type\n", stdout);
			fputs(" -d, --device <path>          block device\n", stdout);
			fputs(" -p, --nopartno               don't set partno (use default)\n", stdout);
			fputs(" -h, --help                   this help\n", stdout);
			fputs(USAGE_SEPARATOR, stdout);
			return EXIT_SUCCESS;
		}
	}

	if (!device)
		errx(EXIT_FAILURE, "no device specified");
	if (!label)
		label = "dos";

	cxt = fdisk_new_context();
	if (!cxt)
		err_oom();
	fdisk_set_ask(cxt, ask_callback, NULL);

	if (grain)
		fdisk_save_user_grain(cxt, grain);

	pa = fdisk_new_partition();
	if (!pa)
		err_oom();

	if (fdisk_assign_device(cxt, device, 0))
		err(EXIT_FAILURE, "failed to assign device");
	if (fdisk_create_disklabel(cxt, label))
		err(EXIT_FAILURE, "failed to create disk label");

	sectorsize = fdisk_get_sector_size(cxt);

	fdisk_disable_dialogs(cxt, 1);

	while (optind < argc) {
		int rc;
		uint64_t size;
		const char *str = argv[optind];

		/* defaults */
		fdisk_partition_start_follow_default(pa, 1);
		fdisk_partition_end_follow_default(pa, 1);
		fdisk_partition_partno_follow_default(pa, 1);

		/* set size */
		if (isdigit(*str)) {
			size = strtosize_or_err(argv[optind], "failed to parse partition size");
			fdisk_partition_set_size(pa, size / sectorsize);
			fdisk_partition_end_follow_default(pa, 0);

		} else if (*str == '-') {
			fdisk_partition_end_follow_default(pa, 1);
		}

		if (fdisk_is_label(cxt, DOS)) {
			/* For MBR we want to avoid primary/logical dialog.
			 * This is possible by explicitly specified partition
			 * number, <4 means primary, >=4 means logical.
			 */
			if (!nopartno) {
				fdisk_partition_partno_follow_default(pa, 0);
				fdisk_partition_set_partno(pa, n);
			}

			/* Make sure last primary partition is extended if user
			 * wants more than 4 partitions.
			 */
			if (n == 3 && optind + 1 < argc) {
				struct fdisk_parttype *type =
					fdisk_label_parse_parttype(
							fdisk_get_label(cxt, NULL), "05");
				if (!type)
					err_oom();
				fdisk_partition_set_type(pa, type);
				fdisk_unref_parttype(type);
			}
		}

		rc = fdisk_add_partition(cxt, pa, NULL);
		if (rc) {
			errno = -rc;
			errx(EXIT_FAILURE, "failed to add #%d partition", n + 1);
		}

		fdisk_reset_partition(pa);
		optind++;
		n++;
	}

	if (fdisk_write_disklabel(cxt))
		err(EXIT_FAILURE, "failed to write disk label");

	fdisk_deassign_device(cxt, 1);
	fdisk_unref_context(cxt);
	fdisk_unref_partition(pa);

	return EXIT_SUCCESS;
}
