/*
 * NPLL - Block device partitions
 *
 * Copyright (C) 2025-2026 Techflash
 */

#ifndef _PARTITION_H
#define _PARTITION_H

#include <npll/types.h>

struct partition {
	/* block device that contains this partition */
	struct blockDevice *bdev;

	/* byte offset of the partition within the block device */
	u64 offset;

	/* size of the partition in bytes */
	u64 size;

	/* partition type (e.g. MBR type byte) */
	u8 type;

	/* partition index (0-based) */
	uint index;
};

/* https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs */
/* deliberately ignoring ones we have no reason to care about here because it's an absolute clusterfuck */
enum mbrType {
	MBR_TYPE_EMPTY = 0x00,
	MBR_TYPE_FAT12 = 0x01,
	MBR_TYPE_FAT16_SMALL = 0x04,
	MBR_TYPE_EXTENDED_CHS = 0x05,
	MBR_TYPE_FAT16_LARGE = 0x06,
	MBR_TYPE_NTFS = 0x07,
	MBR_TYPE_EXFAT = 0x07,
	MBR_TYPE_COMMODORE_FAT12_FAT16_LBA = 0x08,
	MBR_TYPE_OS2_FAT = 0x08,
	MBR_TYPE_FAT32_CHS = 0x0b,
	MBR_TYPE_FAT32_LBA = 0x0c,
	MBR_TYPE_FAT16_LBA = 0x0e,
	MBR_TYPE_EXTENDED_LBA = 0x0f,
	MBR_TYPE_LEADING_EDGE_FAT12_FAT16_LBA = 0x11,
	MBR_TYPE_OS2_HIDDEN_FAT12 = 0x11,
	MBR_TYPE_COMPAQ_CONFIG_FAT = 0x12,
	MBR_TYPE_NCR_DIAG_FAT = 0x12,
	MBR_TYPE_INTEL_SERVICE_FAT = 0x12,
	MBR_TYPE_AST_FAT12_FAT16_LBA = 0x14,
	MBR_TYPE_FAT16_HIDDEN = 0x14,
	MBR_TYPE_OS2_HIDDEN_EXTENDED_CHS = 0x15,
	MBR_TYPE_OS2_HIDDEN_FAT16 = 0x16,
	MBR_TYPE_OS2_HIDDEN_NTFS = 0x17,
	MBR_TYPE_OS2_HIDDEN_EXFAT = 0x17,
	MBR_TYPE_OS2_HIDDEN_FAT32_CHS = 0x1b,
	MBR_TYPE_OS2_HIDDEN_FAT32_LBA = 0x1c,
	MBR_TYPE_ASUS_HIDDEN_FAT32_LBA = 0x1c,
	MBR_TYPE_OS2_HIDDEN_FAT16_LBA = 0x1e,
	MBR_TYPE_OS2_HIDDEN_EXTENDED_LBA = 0x1f,
	MBR_TYPE_NEC_FAT12_FAT16_LBA = 0x24,
	MBR_TYPE_WINRE_NTFS = 0x27,
	MBR_TYPE_ACER_RECOVERY_NTFS = 0x27,
	MBR_TYPE_OLD_LINUX_MINIX = 0x41,
	MBR_TYPE_OLD_LINUX = 0x43,
	MBR_TYPE_ATT_FAT12_FAT16_LBA = 0x56,
	MBR_TYPE_SPEEDSTOR_HIDDEN_RO_FAT12 = 0x63,
	MBR_TYPE_SPEEDSTOR_HIDDEN_RO_FAT16 = 0x64,
	MBR_TYPE_SPEEDSTOR_HIDDEN_RO_FAT16_2 = 0x66,
	MBR_TYPE_APTI_FAT12 = 0x72,
	MBR_TYPE_SPEEDSTOR_HIDDEN_RW_FAT16 = 0x74,
	MBR_TYPE_SPEEDSTOR_HIDDEN_RO_FAT16_LARGE = 0x76,
	MBR_TYPE_APTI_FAT16_SMALL = 0x79,
	MBR_TYPE_APTI_FAT16_LBA = 0x7a,
	MBR_TYPE_APTI_FAT16_LARGE = 0x7b,
	MBR_TYPE_APTI_FAT32_LBA = 0x7c,
	MBR_TYPE_APTI_FAT32_CHS = 0x7d,
	MBR_TYPE_MINIX_OLD = 0x80,
	MBR_TYPE_MINIX = 0x81,
	MBR_TYPE_LINUX = 0x83,
	MBR_TYPE_OS2_HIDDEN_FAT16_C_DRIVE = 0x84,
	MBR_TYPE_EXTENDED_LINUX = 0x85,
	MBR_TYPE_FAULT_TOLERANT_FAT16 = 0x86,
	MBR_TYPE_FAULT_TOLERANT_NTFS = 0x87,
	MBR_TYPE_FAULT_TOLERANT_FAT32_CHS = 0x8b,
	MBR_TYPE_FAULT_TOLERANT_FAT32_LBA = 0x8c,
	MBR_TYPE_FREEDOS_HIDDEN_FAT12 = 0x8d,
	MBR_TYPE_FREEDOS_HIDDEN_FAT16_SMALL = 0x90,
	MBR_TYPE_FREEDOS_HIDDEN_EXTENDED_CHS = 0x91,
	MBR_TYPE_FREEDOS_HIDDEN_FAT16_LARGE = 0x92,
	MBR_TYPE_LINUX_HIDDEN = 0x93,
	MBR_TYPE_ISO9660 = 0x96,
	MBR_TYPE_FREEDOS_HIDDEN_FAT32_CHS = 0x97,
	MBR_TYPE_FREEDOS_HIDDEN_FAT32_LBA = 0x98,
	MBR_TYPE_DATALIGHT_SERVICE_FAT = 0x98,
	MBR_TYPE_INTEL_SERVICE_FAT_2 = 0x98,
	MBR_TYPE_FREEDOS_HIDDEN_FAT16_LBA = 0x9a,
	MBR_TYPE_FREEDOS_HIDDEN_EXTENDED_LBA = 0x9b,
	MBR_TYPE_LINUX_HIDDEN_2 = 0xc2,
	MBR_TYPE_DELL_FAT32_SYSTEM_RESTORE = 0xdb,
	MBR_TYPE_DELL_FAT16_DIAG = 0xde,
	MBR_TYPE_SPEEDSTOR_FAT12 = 0xe1,
	MBR_TYPE_SPEEDSTOR_RO_FAT12 = 0xe3,
	MBR_TYPE_SPEEDSTOR_FAT16 = 0xe4,
	MBR_TYPE_TANDY_FAT12_FAT16_LBA = 0xe5,
	MBR_TYPE_SPEEDSTOR_RO_FAT16 = 0xe6,
	MBR_TYPE_GPT_PMBR = 0xee,
	MBR_TYPE_EFI_SYSTEM_PARTITION = 0xef,
	MBR_TYPE_DRDOS_FAT12_FAT16_LBA = 0xf2,
	MBR_TYPE_SPEEDSTOR_FAT16_LARGE = 0xf4,
	MBR_TYPE_SPEEDSTOR_RO_FAT16_LARGE = 0xf6
};

/* MBR partition table entry (on-disk layout) */
struct __attribute__((packed)) mbrEntry {
	u8 status;
	u8 chsFirst[3];
	u8 type;
	u8 chsLast[3];
	u32 lbaStart;
	u32 sectors;
};

/* MBR top-level format; also applies for extended partitions */
struct __attribute__((packed)) mbr {
	u8 bootCode[446];
	struct mbrEntry entries[4];
	u8 sig[2]; /* 55 aa */
};

void P_ProbePartitions(struct blockDevice *bdev);

#endif /* _PARTITION_H */
