#if ENABLE_FEATURE_GPT_LABEL
/*
 * Copyright (C) 2010 Kevin Cernekee <cernekee@gmail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

#define GPT_MAGIC 0x5452415020494645ULL
enum {
	LEGACY_GPT_TYPE = 0xee,
	GPT_MAX_PARTS   = 256,
	GPT_MAX_PART_ENTRY_LEN = 4096,
	GUID_LEN        = 16,
};

typedef struct {
	uint64_t magic;
	uint32_t revision;
	uint32_t hdr_size;
	uint32_t hdr_crc32;
	uint32_t reserved;
	uint64_t current_lba;
	uint64_t backup_lba;
	uint64_t first_usable_lba;
	uint64_t last_usable_lba;
	uint8_t  disk_guid[GUID_LEN];
	uint64_t first_part_lba;
	uint32_t n_parts;
	uint32_t part_entry_len;
	uint32_t part_array_crc32;
} gpt_header;

typedef struct {
	uint8_t  type_guid[GUID_LEN];
	uint8_t  part_guid[GUID_LEN];
	uint64_t lba_start;
	uint64_t lba_end;
	uint64_t flags;
	uint16_t name[36];
} gpt_partition;

static gpt_header *gpt_hdr;

static char *part_array;
static unsigned int n_parts;
static unsigned int part_array_len;
static unsigned int part_entry_len;

static inline gpt_partition *
gpt_part(unsigned i)
{
	if (i >= n_parts) {
		return NULL;
	}
	return (gpt_partition *)&part_array[i * part_entry_len];
}

static uint32_t
gpt_crc32(void *buf, int len)
{
	return ~crc32_block_endian0(0xffffffff, buf, len, global_crc32_table);
}

static void
gpt_print_guid(uint8_t *buf)
{
	printf(
		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
		buf[3], buf[2], buf[1], buf[0],
		buf[5], buf[4],
		buf[7], buf[6],
		buf[8], buf[9],
		buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
}

/* TODO: real unicode support */
static void
gpt_print_wide(uint16_t *s, int max_len)
{
	int i = 0;

	while (i < max_len) {
		if (*s == 0)
			return;
		fputc(*s, stdout);
		s++;
	}
}

static void
gpt_list_table(int xtra UNUSED_PARAM)
{
	unsigned i;
	char numstr6[6];

	smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0';
	printf("Disk %s: %llu sectors, %s\n", disk_device,
		(unsigned long long)total_number_of_sectors,
		numstr6);
	printf("Logical sector size: %u\n", sector_size);
	printf("Disk identifier (GUID): ");
	gpt_print_guid(gpt_hdr->disk_guid);
	printf("\nPartition table holds up to %u entries\n",
		(int)SWAP_LE32(gpt_hdr->n_parts));
	printf("First usable sector is %llu, last usable sector is %llu\n\n",
		(unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
		(unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));

	printf("Number  Start (sector)    End (sector)  Size       Code  Name\n");
	for (i = 0; i < n_parts; i++) {
		gpt_partition *p = gpt_part(i);
		if (p->lba_start) {
			smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
				numstr6, " KMGTPEZY")[0] = '\0';
			printf("%4u %15llu %15llu %11s   %04x  ",
				i + 1,
				(unsigned long long)SWAP_LE64(p->lba_start),
				(unsigned long long)SWAP_LE64(p->lba_end),
				numstr6,
				0x0700 /* FIXME */);
			gpt_print_wide(p->name, 18);
			printf("\n");
		}
	}
}

static int
check_gpt_label(void)
{
	struct partition *first = pt_offset(MBRbuffer, 0);
	struct pte pe;
	uint32_t crc;

	/* LBA 0 contains the legacy MBR */

	if (!valid_part_table_flag(MBRbuffer)
	 || first->sys_ind != LEGACY_GPT_TYPE
	) {
		current_label_type = 0;
		return 0;
	}

	/* LBA 1 contains the GPT header */

	read_pte(&pe, 1);
	gpt_hdr = (void *)pe.sectorbuffer;

	if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
		current_label_type = 0;
		return 0;
	}

	if (!global_crc32_table) {
		global_crc32_table = crc32_filltable(NULL, 0);
	}

	crc = SWAP_LE32(gpt_hdr->hdr_crc32);
	gpt_hdr->hdr_crc32 = 0;
	if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) {
		/* FIXME: read the backup table */
		puts("\nwarning: GPT header CRC is invalid\n");
	}

	n_parts = SWAP_LE32(gpt_hdr->n_parts);
	part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len);
	if (n_parts > GPT_MAX_PARTS
	 || part_entry_len > GPT_MAX_PART_ENTRY_LEN
	 || SWAP_LE32(gpt_hdr->hdr_size) > sector_size
	) {
		puts("\nwarning: unable to parse GPT disklabel\n");
		current_label_type = 0;
		return 0;
	}

	part_array_len = n_parts * part_entry_len;
	part_array = xmalloc(part_array_len);
	seek_sector(SWAP_LE64(gpt_hdr->first_part_lba));
	if (full_read(dev_fd, part_array, part_array_len) != (ssize_t) part_array_len) {
		fdisk_fatal(unable_to_read);
	}

	if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) {
		/* FIXME: read the backup table */
		puts("\nwarning: GPT array CRC is invalid\n");
	}

	puts("Found valid GPT with protective MBR; using GPT\n");

	current_label_type = LABEL_GPT;
	return 1;
}

#endif /* GPT_LABEL */
