// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package gpt is an implementation of GUID Partition Table read and write. It
// is based on the UEFI specification v2.6.
package gpt

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"hash/crc32"
	"io"
	"math"
	"os"
	"strings"
	"unicode/utf16"

	"go.fuchsia.dev/fuchsia/garnet/go/src/thinfs/mbr"
)

// ErrInvalidGPT aggregates zero or more errors that occur during validation
type ErrInvalidGPT []error

func (e ErrInvalidGPT) Error() string {
	errStrings := make([]string, len(e))
	for i, err := range e {
		errStrings[i] = err.Error()
	}
	return "gpt: invalid GPT: " + strings.Join(errStrings, " and ")
}

var (
	// ErrInvalidSignature indicates that the GPT contained an invalid signature
	ErrInvalidSignature = errors.New("gpt: invalid signature")
	// ErrInvalidAddress indicates that an LBA address in a header or partition
	// table points to an invalid location, either overlapping or out of range.
	ErrInvalidAddress = errors.New("gpt: invalid address")
	// ErrHeaderCRC indicates that a header contained an invalid CRC
	ErrHeaderCRC = errors.New("gpt: bad header CRC")

	// ErrUnsupportedPlatform is returned by functions that are not implemented on
	// the host plaform
	ErrUnsupportedPlatform = errors.New("gpt: unsupported platform")
)

// GUID is a 128 bit globally unique identifier
type GUID struct {
	TimeLow uint32
	TimeMid uint16
	TimeHi  uint16
	SeqHi   byte
	SeqLo   byte
	Node    [6]byte
}

// NewGUID constructs a GUID from a string in hexidecimal form, with arbitrary
// splits containing hyphens.
func NewGUID(s string) (GUID, error) {
	h := strings.Join(strings.Split(s, "-"), "")

	b := make([]byte, 16)
	_, err := hex.Decode(b, []byte(h))
	if err != nil {
		return GUID{}, err
	}

	var g GUID
	return g, binary.Read(bytes.NewReader(b), binary.BigEndian, &g)
}

// NewRandomGUID generates a new entirely random GUID
func NewRandomGUID() GUID {
	// TODO(raggi): strictly speaking this isn't conformant to a paticular GUID
	// version, but it is also reasonable for the use case
	var g GUID
	err := binary.Read(rand.Reader, binary.LittleEndian, &g)
	if err != nil {
		panic(err)
	}
	return g
}

func (g GUID) String() string {
	var buf bytes.Buffer

	binary.Write(&buf, binary.BigEndian, g)

	b := buf.Bytes()
	return fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
}

// IsZero returns true if all fields in the GUID are zero
func (g GUID) IsZero() bool {
	if g.TimeLow != 0 || g.TimeMid != 0 || g.TimeHi != 0 || g.SeqHi != 0 || g.SeqLo != 0 {
		return false
	}
	for _, b := range g.Node {
		if b != 0 {
			return false
		}
	}
	return true
}

// Name looks up the guid in the GUIDS map, and returns the name if found,
// otherwise it returns the standard string representation.
func (g GUID) Name() string {
	for name, ng := range GUIDS {
		if ng == g {
			return name
		}
	}
	return g.String()
}

// Signature is the representation of a GPT signature, normally `EFI PART`
type Signature [8]byte

func (s Signature) String() string {
	return string(s[:])
}

// EFISignature is the default EFI Signature for GPT `EFI PART`
var EFISignature = Signature{'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T'}

// Revision is the 2 byte representation of a GPT revision number
type Revision [4]byte

func (r Revision) String() string {
	return fmt.Sprintf("%d.%d", binary.LittleEndian.Uint16(r[2:]), binary.LittleEndian.Uint16(r[0:2]))
}

// EFIRevision is the 1.0 EFI revision
var EFIRevision = Revision{0, 0, 1, 0}

// HeaderSize is the byte size of a GPT Header
const HeaderSize = 92

// Header is the Go struct represtation of a GPT header
type Header struct {
	Signature                Signature
	Revision                 Revision
	HeaderSize               uint32
	HeaderCRC32              uint32
	Reserved                 [4]byte
	MyLBA                    uint64
	AlternateLBA             uint64
	FirstUsableLBA           uint64
	LastUsableLBA            uint64
	DiskGUID                 GUID
	PartitionEntryLBA        uint64
	NumberOfPartitionEntries uint32
	SizeOfPartitionEntry     uint32
	PartitionEntryArrayCRC32 uint32
}

// ReadFrom reads from the given reader into the reciever header. If an error
// occurs, the returned bytes read may be incorrect.
func (h *Header) ReadFrom(r io.Reader) (int64, error) {
	return HeaderSize, binary.Read(r, binary.LittleEndian, h)
}

// WriteTo writes the header to the given writer. If an error ocurrs, the
// returned bytes written may be incorrect.
func (h *Header) WriteTo(w io.Writer) (int64, error) {
	return HeaderSize, binary.Write(w, binary.LittleEndian, h)
}

func (h Header) String() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "Signature: %s\n", h.Signature)
	fmt.Fprintf(&b, "Revision: %s\n", h.Revision)
	fmt.Fprintf(&b, "HeaderSize: %d\n", h.HeaderSize)
	fmt.Fprintf(&b, "HeaderCRC32: %d\n", h.HeaderCRC32)
	fmt.Fprintf(&b, "MyLBA: %d\n", h.MyLBA)
	fmt.Fprintf(&b, "AlternateLBA: %d\n", h.AlternateLBA)
	fmt.Fprintf(&b, "FirstUsableLBA: %d\n", h.FirstUsableLBA)
	fmt.Fprintf(&b, "LastUsableLBA: %d\n", h.LastUsableLBA)
	fmt.Fprintf(&b, "DiskGUID: %s\n", h.DiskGUID)
	fmt.Fprintf(&b, "PartitionEntryLBA: %d\n", h.PartitionEntryLBA)
	fmt.Fprintf(&b, "NumberOfPartitionEntries: %d\n", h.NumberOfPartitionEntries)
	fmt.Fprintf(&b, "SizeOfPartitionEntry: %d\n", h.SizeOfPartitionEntry)
	fmt.Fprintf(&b, "PartitionEntryArrayCRC32: %d\n", h.PartitionEntryArrayCRC32)
	return b.String()
}

// MinPartitionEntryArraySize is the minimum allowed size of a GPT partition array
const MinPartitionEntryArraySize = 16384

// PartitionName is a 32 character string in utf-16
type PartitionName [72]byte

// NewPartitionName constructs a partition name from the given string (encodes
// it in utf16 and truncates it to 32 characters.
func NewPartitionName(s string) PartitionName {
	var b bytes.Buffer
	var pn PartitionName
	binary.Write(&b, binary.LittleEndian, utf16.Encode([]rune(s)))
	copy(pn[:], b.Bytes())
	return pn
}

func (pn PartitionName) String() string {
	var chars []uint16
	for i := 0; i < len(pn); i += 2 {
		if pn[i] == 0 && pn[i+1] == 0 {
			break
		}
		chars = append(chars, binary.LittleEndian.Uint16(pn[i:i+2]))
	}

	return string(utf16.Decode(chars))
}

// PartitionEntrySize is the size of the partition entry structure
const PartitionEntrySize = 128

// PartitionEntry is the Go structure representation of a partition in GPT
type PartitionEntry struct {
	PartitionTypeGUID   GUID
	UniquePartitionGUID GUID
	StartingLBA         uint64
	EndingLBA           uint64
	Attributes          uint64
	PartitionName       PartitionName
}

// ReadFrom reads from the given reader into the reciever PartitionEntry. If an
// error occurs, the returned bytes read may be incorrect.
func (p *PartitionEntry) ReadFrom(r io.Reader) (int64, error) {
	return PartitionEntrySize, binary.Read(r, binary.LittleEndian, p)
}

// WriteTo writes the PartitionEntry to the given writer.
func (p *PartitionEntry) WriteTo(w io.Writer) (int64, error) {
	return PartitionEntrySize, binary.Write(w, binary.LittleEndian, p)
}

// IsZero returns true if the partition entry is unused
func (p *PartitionEntry) IsZero() bool {
	if p.UniquePartitionGUID == GUIDUnused {
		return true
	}
	return false
}

func (p PartitionEntry) String() string {
	var b bytes.Buffer

	fmt.Fprintf(&b, "PartitionTypeGUID: %s\n", p.PartitionTypeGUID.Name())
	fmt.Fprintf(&b, "UniquePartitionGUID: %s\n", p.UniquePartitionGUID)
	fmt.Fprintf(&b, "StartingLBA: %d\n", p.StartingLBA)
	fmt.Fprintf(&b, "EndingLBA: %d\n", p.EndingLBA)
	fmt.Fprintf(&b, "Attributes: %d\n", p.Attributes)
	fmt.Fprintf(&b, "PartitionName: %s\n", p.PartitionName)

	return b.String()
}

// Partition Attributes
const (
	RequiredPartition  = 0
	NoBlockIOProtocol  = 1
	LegacyBIOSBootable = 2

	MicrosoftReadOnly      = 60
	MicrosoftShadowCopy    = 61
	MicrosoftHidden        = 62
	MicrosoftNoDriveLetter = 63
)

func mustNewGUID(s string) GUID {
	g, err := NewGUID(s)
	if err != nil {
		panic(err)
	}
	return g
}

// PartitionGUIDs:
var (
	GUIDUnused           = mustNewGUID("00000000-0000-0000-0000-000000000000")
	GUIDMBR              = mustNewGUID("024DEE41-33E7-11D3-9D69-0008C781F39F")
	GUIDEFI              = mustNewGUID("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")
	GUIDBIOS             = mustNewGUID("21686148-6449-6E6F-744E-656564454649")
	GUIDIntelFastFlash   = mustNewGUID("D3BFE2DE-3DAF-11DF-BA40-E3A556D89593")
	GUIDSonyBoot         = mustNewGUID("F4019732-066E-4E12-8273-346C5641494F")
	GUIDLenovoBoot       = mustNewGUID("BFBFAFE7-A34F-448A-9A5B-6213EB736C22")
	GUIDAppleHFSPlus     = mustNewGUID("48465300-0000-11AA-AA11-00306543ECAC")
	GUIDAppleUFS         = mustNewGUID("55465300-0000-11AA-AA11-00306543ECAC")
	GUIDAppleBoot        = mustNewGUID("426F6F74-0000-11AA-AA11-00306543ECAC")
	GUIDAppleRaid        = mustNewGUID("52414944-0000-11AA-AA11-00306543ECAC")
	GUIDAppleOfflineRAID = mustNewGUID("52414944-5F4F-11AA-AA11-00306543ECAC")
	GUIDAppleLabel       = mustNewGUID("4C616265-6C00-11AA-AA11-00306543ECAC")
	GUIDFuchsiaSystem    = mustNewGUID("606B000B-B7C7-4653-A7D5-B737332C899D")
	GUIDFuchsiaData      = mustNewGUID("08185F0C-892D-428A-A789-DBEEC8F55E6A")
	GUIDFuchsiaBlob      = mustNewGUID("2967380E-134C-4CBB-B6DA-17E7CE1CA45D")
	GUIDFuchsiaFVM       = mustNewGUID("41D0E340-57E3-954E-8C1E-17ECAC44CFF5")
	GUIDFuchsiaZirconA   = mustNewGUID("DE30CC86-1F4A-4A31-93C4-66F147D33E05")
	GUIDFuchsiaZirconB   = mustNewGUID("23CC04DF-C278-4CE7-8471-897D1A4BCDF7")
	GUIDFuchsiaZirconR   = mustNewGUID("A0E5CF57-2DEF-46BE-A80C-A2067C37CD49")
)

// GUIDS contains a map of known GUIDS to their names.
var GUIDS = map[string]GUID{
	// TODO(raggi): make / find / use a generator to manage this list and the
	// above
	"unused":             GUIDUnused,
	"mbr":                GUIDMBR,
	"efi":                GUIDEFI,
	"bios":               GUIDBIOS,
	"intel-fast-flash":   GUIDIntelFastFlash,
	"sony-boot":          GUIDSonyBoot,
	"lenovo-boot":        GUIDLenovoBoot,
	"apple-hfs-plus":     GUIDAppleHFSPlus,
	"apple-ufs":          GUIDAppleUFS,
	"apple-boot":         GUIDAppleBoot,
	"apple-raid":         GUIDAppleRaid,
	"apple-offline-raid": GUIDAppleOfflineRAID,
	"apple-label":        GUIDAppleLabel,
	"fuchsia-system":     GUIDFuchsiaSystem,
	"fuchsia-data":       GUIDFuchsiaData,
	"fuchsia-blob":       GUIDFuchsiaBlob,
	"zircon-a":           GUIDFuchsiaZirconA,
	"zircon-b":           GUIDFuchsiaZirconB,
	"zircon-r":           GUIDFuchsiaZirconR,
}

// ReadHeader reads a single GPT header from r.
func ReadHeader(r io.Reader) (Header, error) {
	var h Header
	_, err := h.ReadFrom(r)
	return h, err
}

// ReadPartitionEntry reads a single GPT PartitionEntry from r.
func ReadPartitionEntry(r io.Reader) (PartitionEntry, error) {
	var p PartitionEntry
	return p, binary.Read(r, binary.LittleEndian, &p)
}

// PartitionArray is an array of PartitionEntry
type PartitionArray []PartitionEntry

// WriteTo implements io.WriterTo for PartitionArray. Note that it writes only
// the partition entries stored in the receiver array. Callers are responsible
// for any necessary zero-ing of non-present zero partition entries.
func (pa PartitionArray) WriteTo(w io.Writer) (int64, error) {
	var total int64
	for _, pe := range pa {
		n, err := pe.WriteTo(w)
		total += n
		if err != nil {
			return total, err
		}
	}
	return total, nil
}

// PartitionTable is a header followed by an array of partiton entries
type PartitionTable struct {
	Header
	Partitions PartitionArray
}

// ComputePartitionArrayCRC32 calculates the CRC32 of the contained partition
// array. It does not write the result back to the partition table.
func (pt PartitionTable) ComputePartitionArrayCRC32() uint32 {
	partitionTableCRC32 := crc32.NewIEEE()

	for _, p := range pt.Partitions {
		if _, err := p.WriteTo(partitionTableCRC32); err != nil {
			panic(err)
		}
	}
	// write any left over empty partition entries
	var pe PartitionEntry
	for i := uint32(len(pt.Partitions)); i < pt.NumberOfPartitionEntries; i++ {
		if _, err := pe.WriteTo(partitionTableCRC32); err != nil {
			panic(err)
		}
	}

	return partitionTableCRC32.Sum32()
}

// ComputeHeaderCRC32 calculates the CRC32 of the header. Users may need to call
// ComputePartitionArrayCRC32 before calling this method. It does not write the
// result back to the partition table.
func (pt PartitionTable) ComputeHeaderCRC32() uint32 {
	headerCRC32 := crc32.NewIEEE()
	pt.HeaderCRC32 = 0
	if _, err := pt.WriteTo(headerCRC32); err != nil {
		panic(err)
	}

	return headerCRC32.Sum32()
}

func (pt PartitionTable) String() string {
	var b bytes.Buffer

	fmt.Fprintf(&b, "%s\n", pt.Header)
	for i, p := range pt.Partitions {
		if p.IsZero() {
			continue
		}
		fmt.Fprintf(&b, "Partition %d:\n%s\n", i, p)
	}

	return b.String()
}

// PartitionArrayPad calculates the amount of space that must be zero-written
// between the last partition contained in the PartitionArray and the end of the
// on-disk partition array size.
func (pt PartitionTable) PartitionArrayPad() int64 {
	return int64(pt.NumberOfPartitionEntries*pt.SizeOfPartitionEntry) - int64(len(pt.Partitions)*int(pt.SizeOfPartitionEntry))
}

// GPT is a wrapper around a disks MBR, Primary and Backup PartitionTable and
// block size metadata.
type GPT struct {
	MBR     mbr.MBR
	Primary PartitionTable
	Backup  PartitionTable

	logical, physical, optimal, size uint64 // block, transfer and sizes in bytes
}

// ReadGPT reads a GPT from r using the given logical block size.
func ReadGPT(r io.ReadSeeker, blockSize uint64, diskSize uint64) (GPT, error) {
	var g GPT

	if _, err := g.MBR.ReadFrom(r); err != nil {
		return g, err
	}

	if _, err := r.Seek(int64(blockSize), io.SeekStart); err != nil {
		return g, err
	}

	if _, err := g.Primary.ReadFrom(r); err != nil {
		return g, err
	}

	if g.Primary.ComputeHeaderCRC32() == g.Primary.HeaderCRC32 {
		ptLoc := int64(g.Primary.PartitionEntryLBA * uint64(blockSize))
		if _, err := r.Seek(ptLoc, io.SeekStart); err != nil {
			return g, err
		}

		// Avoid divide by zero, recover any possibly readable data..
		if g.Primary.SizeOfPartitionEntry == 0 {
			g.Primary.SizeOfPartitionEntry = PartitionEntrySize
		}

		// the minimium number of partitions is defined by the minimum allowed size
		numPartitions := MinPartitionEntryArraySize / g.Primary.SizeOfPartitionEntry
		if numPartitions < g.Primary.NumberOfPartitionEntries {
			numPartitions = g.Primary.NumberOfPartitionEntries
		}
		g.Primary.Partitions = make([]PartitionEntry, numPartitions)

		pePad := int64(g.Primary.SizeOfPartitionEntry - PartitionEntrySize)
		for i := range g.Primary.Partitions {
			if _, err := g.Primary.Partitions[i].ReadFrom(r); err != nil {
				return g, err
			}

			if _, err := r.Seek(pePad, io.SeekCurrent); err != nil {
				return g, err
			}
		}
	}

	lastBlock := int64(diskSize - uint64(blockSize))
	if _, err := r.Seek(lastBlock, io.SeekStart); err != nil {
		return g, err
	}

	if _, err := g.Backup.ReadFrom(r); err != nil {
		return g, err
	}

	if g.Backup.ComputeHeaderCRC32() == g.Backup.HeaderCRC32 {
		ptLoc := int64(g.Backup.PartitionEntryLBA * uint64(blockSize))
		if _, err := r.Seek(ptLoc, io.SeekStart); err != nil {
			return g, err
		}

		// Avoid divide by zero, recover any possibly readable data..
		if g.Backup.SizeOfPartitionEntry == 0 {
			g.Backup.SizeOfPartitionEntry = PartitionEntrySize
		}

		numPartitions := MinPartitionEntryArraySize / g.Backup.SizeOfPartitionEntry
		if numPartitions < g.Backup.NumberOfPartitionEntries {
			numPartitions = g.Backup.NumberOfPartitionEntries
		}
		g.Backup.Partitions = make([]PartitionEntry, numPartitions)

		pePad := int64(g.Backup.SizeOfPartitionEntry - PartitionEntrySize)
		for i := range g.Backup.Partitions {
			if _, err := g.Backup.Partitions[i].ReadFrom(r); err != nil {
				return g, err
			}

			if _, err := r.Seek(pePad, io.SeekCurrent); err != nil {
				return g, err
			}
		}
	}

	return g, nil
}

// nullReader is a convenience for cross-platform io.copy of 0 bytes to a target
// writer.
type nullReader struct{}

func (nr nullReader) Read(b []byte) (int, error) {
	for i := range b {
		b[i] = 0
	}
	return len(b), nil
}

func seekOrWrite(w io.Writer, n int64) (int64, error) {
	if seeker, canSeek := w.(io.Seeker); canSeek {
		_, err := seeker.Seek(n, io.SeekCurrent)
		return 0, err
	}
	return io.CopyN(w, nullReader{}, n)
}

// WriteTo implements io.WriterTo for writing out the GPT to a target writer. It
// expects that update was called with correct values beforehand, but it will,
// if otherwise un-set try to detect reasonable values for logical and physical
// block sizes. If the target writer does not support detection of these sizes,
// and they were not supplied to Update, the write will make conventional
// assumptions (logical block size: 512, physical block size: 4096). Note: If
// the given writer does not implement io.Seeker, then the write will zero out
// all non-partition data regions. If the argument implements io.Seeker, then
// all non-partition table data will remain untouched.
func (g *GPT) WriteTo(w io.Writer) (int64, error) {
	if f, ok := w.(*os.File); ok {
		if g.logical == 0 {
			g.logical, _ = GetLogicalBlockSize(f)
		}
		if g.physical == 0 {
			g.physical, _ = GetPhysicalBlockSize(f)
		}
		// TODO(raggi): try to find out optimal transfer sizes
	}
	if g.logical == 0 {
		g.logical = FallbackLogicalBlockSize
	}
	if g.physical == 0 {
		g.physical = FallbackPhysicalBlockSize
	}

	var total int64

	if seeker, canSeek := w.(io.Seeker); canSeek {
		if _, err := seeker.Seek(0, io.SeekStart); err != nil {
			return total, err
		}
	}

	// MBR...
	n, err := g.MBR.WriteTo(w)
	total += n
	if err != nil {
		return total, err
	}

	// write zero's up to the second block
	n, err = io.CopyN(w, nullReader{}, total-int64(g.logical))
	total += n
	if err != nil {
		return total, err
	}

	// Primary...
	n, err = g.Primary.Header.WriteTo(w)
	total += n
	if err != nil {
		return total, err
	}

	if total%int64(g.logical) != 0 {
		n, err = io.CopyN(w, nullReader{}, int64(g.logical)-total%int64(g.logical))
		total += n
		if err != nil {
			return total, err
		}
	}

	n, err = g.Primary.Partitions.WriteTo(w)
	total += n
	if err != nil {
		return total, err
	}

	n, err = io.CopyN(w, nullReader{}, g.Primary.PartitionArrayPad())
	total += n
	if err != nil {
		return total, err
	}

	// Backup...

	n, err = seekOrWrite(w, int64(g.Backup.PartitionEntryLBA*g.logical)-total)
	total += n
	if err != nil {
		return total, err
	}

	n, err = g.Backup.Partitions.WriteTo(w)
	total += n
	if err != nil {
		return total, err
	}

	n, err = io.CopyN(w, nullReader{}, g.Primary.PartitionArrayPad())
	total += n
	if err != nil {
		return total, err
	}
	if total%int64(g.logical) != 0 {
		n, err = io.CopyN(w, nullReader{}, int64(g.logical)-total%int64(g.logical))
		total += n
		if err != nil {
			return total, err
		}
	}

	n, err = g.Backup.Header.WriteTo(w)
	total += n
	if err != nil {
		return total, err
	}
	if total%int64(g.logical) != 0 {
		n, err = io.CopyN(w, nullReader{}, int64(g.logical)-total%int64(g.logical))
		total += n
		if err != nil {
			return total, err
		}
	}

	return total, err
}

func (g GPT) String() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "MBR:\n%s\n\n", g.MBR)
	if g.Primary.Signature == EFISignature {
		fmt.Fprintf(&b, "GPT Primary:\n%s\n\n", g.Primary)
	}
	if g.Backup.Signature == EFISignature {
		fmt.Fprintf(&b, "GPT Backup:\n%s\n\n", g.Backup)
	}
	fmt.Fprintf(&b, "GPT Valid: %v\n", g.Validate() == nil)
	return b.String()
}

// Update uses the provided geometry information, combined with the values
// already present in g to update the geometry and CRC fields for the tables and
// partitions in g. If the changes make laying out the partitions impossible, an
// error is returned. Subsequent calls to WriteTo will use the given values if
// non-zero. Note that partition re-alignment will only move partition starts
// forward, it will not preserve size, so callers must set partition starting
// positions appropriately using NextAlignedLBA to avoid this.
func (g *GPT) Update(blockSize, physicalBlockSize, optimalTransferLengthGranularity, diskSize uint64) error {
	g.logical = blockSize
	g.physical = physicalBlockSize
	g.optimal = optimalTransferLengthGranularity
	g.size = diskSize

	// Various fields in the GPT have known constant values, they're setup first
	g.Primary.Signature = EFISignature
	g.Primary.Revision = EFIRevision
	g.Primary.HeaderSize = HeaderSize
	g.Primary.Reserved = [4]byte{}
	g.Primary.SizeOfPartitionEntry = PartitionEntrySize

	// The primary partition array always starts at logical block 2
	g.Primary.PartitionEntryLBA = 2

	// The number of non-zero partition entries
	paSize := uint32(len(g.Primary.Partitions)) * g.Primary.SizeOfPartitionEntry
	if paSize < MinPartitionEntryArraySize {
		paSize = MinPartitionEntryArraySize
	}
	g.Primary.NumberOfPartitionEntries = uint32(paSize / g.Primary.SizeOfPartitionEntry)

	// The first usable block is located after the end of the partition array
	ptBlockSize := uint64(paSize) / blockSize
	diskBlockSize := diskSize / blockSize
	headerBlockSize := uint64(g.Primary.HeaderSize)
	if headerBlockSize < blockSize {
		headerBlockSize = blockSize
	}
	headerBlockSize = headerBlockSize / blockSize

	g.Primary.MyLBA = 1
	g.Primary.FirstUsableLBA = 2 + ptBlockSize
	g.Primary.LastUsableLBA = diskBlockSize - ptBlockSize - uint64(headerBlockSize) - 1
	g.Primary.AlternateLBA = diskBlockSize - 1

	if g.Primary.DiskGUID.IsZero() {
		g.Primary.DiskGUID = NewRandomGUID()
	}

	nextUsableLBA := g.Primary.FirstUsableLBA
	for i := range g.Primary.Partitions {
		var p = &g.Primary.Partitions[i]

		if p.IsZero() {
			continue
		}

		if p.StartingLBA == 0 {
			p.StartingLBA = nextUsableLBA
		}

		p.StartingLBA = NextAlignedLBA(p.StartingLBA, blockSize, physicalBlockSize, optimalTransferLengthGranularity)

		if p.EndingLBA <= p.StartingLBA {
			return fmt.Errorf("partition %s has invalid geometry after alignment", p)
		}
		if p.EndingLBA > diskSize/blockSize {
			return fmt.Errorf("partition %s extends beyond disk geometry", p)
		}

		nextUsableLBA = p.EndingLBA + 1
	}

	// Copy the updated primary data and partition entries to backup
	g.Backup = g.Primary

	// The backup header lives at the last block of the disk
	g.Backup.MyLBA, g.Backup.AlternateLBA = g.Primary.AlternateLBA, g.Primary.MyLBA
	g.Backup.PartitionEntryLBA = g.Backup.LastUsableLBA + 1

	// Update the CRCs
	for _, pt := range []*PartitionTable{&g.Primary, &g.Backup} {
		pt.PartitionEntryArrayCRC32 = pt.ComputePartitionArrayCRC32()
		pt.HeaderCRC32 = pt.ComputeHeaderCRC32()
	}

	return nil
}

// NextAlignedLBA takes a starting LBA, the logical, physical and optimal block
// sizes, and returns the next LBA that conforms the UEFI alignment
// specifications. Unknown values may be passed as 0, but logcal must have a
// reasonable value.
func NextAlignedLBA(nextLBA, logical, physical, optimal uint64) uint64 {
	alignTo := logical
	if physical > alignTo {
		alignTo = physical
	}
	if optimal > alignTo {
		alignTo = optimal
	}
	alignTo = alignTo / logical

	if d := nextLBA % alignTo; d != 0 {
		nextLBA = nextLBA + (alignTo - d)
	}

	return nextLBA
}

// AlignedRange takes a starting lba, size (in bytes), logical, physical and
// optimal block sizes and computes a well-aligned maximal range of block
// addresses starting after nextLBA, and ending to be at most one block larger
// than the requested size.
func AlignedRange(nextLBA, size, logical, physical, optimal uint64) (uint64, uint64) {
	start := NextAlignedLBA(nextLBA, logical, physical, optimal)
	end := NextAlignedLBA(start+upDiv(size, logical)+1, logical, physical, optimal) - 1
	return start, end
}

// upDiv divides two uints, always rounding up.
func upDiv(a, b uint64) uint64 {
	return uint64(math.Ceil(float64(a) / float64(b)))
}

// Validate runs a set of validation operations on the entire GPT, and if errors
// are found, returns them inside ErrInvalidGPT
func (g *GPT) Validate() error {
	// TODO(raggi): the errors array might be better off as a struct that
	// separates errors in primary from errors in backup, and then move the
	// contents of this method onto PartitionTable and call once for each.
	var errors ErrInvalidGPT
	if g.Primary.Signature != EFISignature || g.Backup.Signature != EFISignature {
		errors = append(errors, ErrInvalidSignature)
	}
	if g.Primary.MyLBA != 1 || g.Backup.AlternateLBA != 1 {
		errors = append(errors, ErrInvalidAddress)
	}
	if g.Primary.AlternateLBA != g.Backup.MyLBA || g.Backup.AlternateLBA != g.Primary.MyLBA {
		errors = append(errors, ErrInvalidAddress)
	}

	// Note that this also covers the partition table CRC32, as that is part of
	// the calculation.
	if g.Primary.ComputeHeaderCRC32() != g.Primary.HeaderCRC32 ||
		g.Backup.ComputeHeaderCRC32() != g.Backup.HeaderCRC32 {
		errors = append(errors, ErrHeaderCRC)
	}

	// TODO(raggi): although it is not required by EFI for booting, and thus not
	// in the spec section about validation, there are rules about not producing
	// overlapping partitions and over-extended partitions that are not checked
	// here. They should be checked somewhere, but that would require a knowledge
	// of the disk size and other such things.

	if errors == nil {
		return nil
	}
	if len(errors) == 0 {
		return nil
	}
	return errors
}

// FallbackPhysicalBlockSize of 4096 is returned (with error) from
// GetPhysicalBlockSize as a sensible default assumption. Devices are tending
// toward this as a common physical sector size, and there isn't much to lose
// from this alignment as opposed to 512, the prior common value. By contrast,
// write performance can be significantly negatively affected by an alignment
// less than this on such disks.
const FallbackPhysicalBlockSize = 4096

// FallbackLogicalBlockSize of 512 is returned (with error) from
// GetLogicalBlockSize as a sensible default assumption.
const FallbackLogicalBlockSize = 512

// regularSize tries to stat the file, if the stat succeeds and the file is a
// regular file, it returns the files size, and true, otherwise 0 and false.
func regularSize(f *os.File) (int64, bool) {
	info, err := f.Stat()
	if err != nil {
		return 0, false
	}

	if info.Mode().IsRegular() {
		return info.Size(), true
	}
	return 0, false
}
