// 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 mbr is a minimial implementation of Master Boot Record parsing and
// writing, implemented in support of GUID Partition Table parsing and writing.
// It is based on the UEFI Specification v2.6.
package mbr

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

// OSType marks the partition type in an MBR Partition Record
//go:generate stringer -type=OSType
type OSType byte

// TODO(raggi): fill in other types and organize from: "Partition types" by
// Andries Brouwer: See "Links to UEFI-Related Documents" (http://uefi.org/uefi)
// under the heading "OS Type values used in the MBR disk layout".
const (
	FAT32               OSType = 0x0b
	UEFISystemPartition OSType = 0xEF
	GPTProtective       OSType = 0xEE
)

// Signature is an MBR Signature as two bytes in little endian.
type Signature uint16

//go:generate stringer -type=Signature
const (
	// GPTSignature is the partition signature of a protective MBR partition
	GPTSignature Signature = 0xAA55
)

// PartitionRecord is a type representing a legacy MBR partition record
type PartitionRecord struct {
	BootIndicator byte
	StartingCHS   [3]byte
	OSType        OSType
	EndingCHS     [3]byte
	StartingLBA   uint32
	SizeInLBA     uint32
}

// MBRSize is the size of an MBR record without logical block size padding
const MBRSize = 512

// MBR is a Go representation of a legacy Master Boot Record.
type MBR struct {
	BootCode               [424]byte // 424 bytes should be enough for anybody...
	Pad                    [16]byte  // unnamed blank space in efi spec?
	UniqueMBRDiskSignature uint32
	Unknown                [2]byte
	PartitionRecord        [4]PartitionRecord
	Signature              Signature
}

// ReadFrom reads from the given io.Reader into the receiver MBR. If an error
// occurs the returned bytes read may be incorrect.
func (m *MBR) ReadFrom(r io.Reader) (int64, error) {
	return MBRSize, binary.Read(r, binary.LittleEndian, m)
}

// WriteTo implements the io.WriterTo interface for MBR. It writes the MBR to
// w in little endian as per the GPT specification.
func (m *MBR) WriteTo(w io.Writer) (int64, error) {
	return MBRSize, binary.Write(w, binary.LittleEndian, m)
}

func (m MBR) String() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "Disk Signature: 0x%X\nSignature: %s\n",
		m.UniqueMBRDiskSignature, m.Signature)
	for i, p := range m.PartitionRecord {
		if p.OSType == OSType(0) && p.StartingLBA == 0 {
			continue
		} else if i > 0 {
			b.Write([]byte("\n"))
		}

		fmt.Fprintf(&b,
			"Boot Indicator: 0x%X\nOS Type: %s\nStarting LBA: 0x%X\nSize In LBA: 0x%X (%d)",
			p.BootIndicator, p.OSType, p.StartingLBA, p.SizeInLBA, p.SizeInLBA)
	}
	return b.String()
}

// WriteProtectiveMBR constructs and writes a protective MBR to w. It will only
// write the first block to w (that is, blockSize bytes).
func WriteProtectiveMBR(w io.Writer, blockSize, numBlocks uint64) error {
	m := NewProtectiveMBR(numBlocks)
	_, err := m.WriteTo(w)
	if err != nil {
		return err
	}
	// TODO(raggi): consider doing this without allocating all that space
	_, err = w.Write(make([]byte, blockSize-MBRSize))
	return err
}

// NewProtectiveMBR constructs an MBR struct with fields conformant to the UEFI
// specification 2.6 "Protective MBR"
func NewProtectiveMBR(numBlocks uint64) MBR {
	var partSizeInLBA32 uint32 = 0xffffffff
	if numBlocks < uint64(partSizeInLBA32) {
		partSizeInLBA32 = uint32(numBlocks) - 1
	}

	return MBR{
		PartitionRecord: [4]PartitionRecord{
			PartitionRecord{
				OSType:      GPTProtective,
				StartingCHS: [3]byte{0, 2, 0},
				// TODO(raggi): correctly calculate endingCHS.
				StartingLBA: 1,
				SizeInLBA:   partSizeInLBA32,
			},
		},
		Signature: GPTSignature,
	}
}

// ReadMBR reads a MasterBootRecord from r.
func ReadMBR(r io.Reader) (*MBR, error) {
	m := &MBR{}
	_, err := m.ReadFrom(r)
	return m, err
}
