/*
 * volume_id - reads filesystem label and uuid
 *
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "volume_id_internal.h"

struct mac_driver_desc {
	uint8_t		signature[2];
	uint16_t	block_size;
	uint32_t	block_count;
} __attribute__((__packed__));

struct mac_partition {
	uint8_t		signature[2];
	uint16_t	res1;
	uint32_t	map_count;
	uint32_t	start_block;
	uint32_t	block_count;
	uint8_t		name[32];
	uint8_t		type[32];
} __attribute__((__packed__));

int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off)
{
	const uint8_t *buf;
	struct mac_driver_desc *driver;
	struct mac_partition *part;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	buf = volume_id_get_buffer(id, off, 0x200);
	if (buf == NULL)
		return -1;

	part = (struct mac_partition *) buf;
	if (part->signature[0] == 'P' && part->signature[1] == 'M' /* "PM" */
	 && (memcmp(part->type, "Apple_partition_map", 19) == 0)
	) {
		/* linux creates an own subdevice for the map
		 * just return the type if the drive header is missing */
//		volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
//		id->type = "mac_partition_map";
		return 0;
	}

	driver = (struct mac_driver_desc *) buf;
	if (driver->signature[0] == 'E' && driver->signature[1] == 'R') { /* "ER" */
		/* we are on a main device, like a CD
		 * just try to probe the first partition from the map */
		unsigned bsize = be16_to_cpu(driver->block_size);
		int part_count;
		int i;

		/* get first entry of partition table */
		buf = volume_id_get_buffer(id, off +  bsize, 0x200);
		if (buf == NULL)
			return -1;

		part = (struct mac_partition *) buf;
		if (part->signature[0] != 'P' || part->signature[1] != 'M') /* not "PM" */
			return -1;

		part_count = be32_to_cpu(part->map_count);
		dbg("expecting %d partition entries", part_count);

		if (id->partitions != NULL)
			free(id->partitions);
		id->partitions = xzalloc(part_count * sizeof(struct volume_id_partition));

		id->partition_count = part_count;

		for (i = 0; i < part_count; i++) {
			uint64_t poff;
			uint64_t plen;

			buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200);
			if (buf == NULL)
				return -1;

			part = (struct mac_partition *) buf;
			if (part->signature[0] != 'P' || part->signature[1] != 'M') /* not "PM" */
				return -1;

			poff = be32_to_cpu(part->start_block) * bsize;
			plen = be32_to_cpu(part->block_count) * bsize;
			dbg("found '%s' partition entry at 0x%llx, len 0x%llx",
					part->type, (unsigned long long) poff,
					(unsigned long long) plen);

//			id->partitions[i].pt_off = poff;
//			id->partitions[i].pt_len = plen;

//			if (memcmp(part->type, "Apple_Free", 10) == 0) {
//				volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNUSED);
//			} else if (memcmp(part->type, "Apple_partition_map", 19) == 0) {
//				volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_PARTITIONTABLE);
//			} else {
//				volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNPROBED);
//			}
		}
//		volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
//		id->type = "mac_partition_map";
		return 0;
	}

	return -1;
}
