// MIT License
//
// Copyright (c) 2021 Philippe Voinov (philippevoinov@gmail.com)
// Copyright 2021 The Monogon Project Authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

package efivarfs

import (
	"fmt"
	"math"
	"strings"

	"github.com/google/uuid"
	"golang.org/x/text/transform"
)

// Note on binary format of EFI variables:
// This code follows Section 3 "Boot Manager" of version 2.6 of the UEFI Spec:
// http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf
// It uses the binary representation from the Linux "efivars" filesystem.
// Specifically, all binary data that is marshaled and unmarshaled is preceded by
// 4 bytes of "Variable Attributes".
// All binary data must have exactly the correct length and may not be padded
// with extra bytes while reading or writing.

// Note on EFI variable attributes:
// This code ignores all EFI variable attributes when reading.
// This code always writes variables with the following attributes:
//   - EFI_VARIABLE_NON_VOLATILE (0x00000001)
//   - EFI_VARIABLE_BOOTSERVICE_ACCESS (0x00000002)
//   - EFI_VARIABLE_RUNTIME_ACCESS (0x00000004)
const defaultAttrsByte0 uint8 = 7

// BootEntry represents a subset of the contents of a Boot#### EFI variable.
type BootEntry struct {
	Description     string // eg. "Linux Boot Manager"
	Path            string // eg. `\EFI\systemd\systemd-bootx64.efi`
	PartitionGUID   uuid.UUID
	PartitionNumber uint32 // Starts with 1
	PartitionStart  uint64 // LBA
	PartitionSize   uint64 // LBA
}

// Marshal generates the binary representation of a BootEntry (EFI_LOAD_OPTION).
// Description, DiskGUID and Path must be set.
// Attributes of the boot entry (EFI_LOAD_OPTION.Attributes, not the same
// as attributes of an EFI variable) are always set to LOAD_OPTION_ACTIVE.
func (t *BootEntry) Marshal() ([]byte, error) {
	if t.Description == "" ||
		t.PartitionGUID.String() == "00000000-0000-0000-0000-000000000000" ||
		t.Path == "" ||
		t.PartitionNumber == 0 ||
		t.PartitionStart == 0 ||
		t.PartitionSize == 0 {
		return nil, fmt.Errorf("missing field, all are required: %+v", *t)
	}

	// EFI_LOAD_OPTION.FilePathList
	var dp []byte

	// EFI_LOAD_OPTION.FilePathList[0]
	dp = append(dp,
		0x04,       // Type ("Media Device Path")
		0x01,       // Sub-Type ("Hard Drive")
		0x2a, 0x00, // Length (always 42 bytes for this type)
	)
	dp = append32(dp, t.PartitionNumber)
	dp = append64(dp, t.PartitionStart)
	dp = append64(dp, t.PartitionSize)
	// Append the partition GUID in the EFI format.
	dp = append(dp, MarshalEFIGUID(t.PartitionGUID)...)

	dp = append(dp,
		0x02, // Partition Format ("GUID Partition Table")
		0x02, // Signature Type ("GUID signature")
	)

	// EFI_LOAD_OPTION.FilePathList[1]
	enc := Encoding.NewEncoder()
	bsp := strings.ReplaceAll(t.Path, "/", "\\")
	path, _, e := transform.Bytes(enc, []byte(bsp))
	if e != nil {
		return nil, fmt.Errorf("while encoding Path: %v", e)
	}
	path = append16(path, 0) // null terminate string
	filePathLen := len(path) + 4
	dp = append(dp,
		0x04, // Type ("Media Device Path")
		0x04, // Sub-Type ("File Path")
	)
	dp = append16(dp, uint16(filePathLen))
	dp = append(dp, path...)

	// EFI_LOAD_OPTION.FilePathList[2] ("Device Path End Structure")
	dp = append(dp,
		0x7F,       // Type ("End of Hardware Device Path")
		0xFF,       // Sub-Type ("End Entire Device Path")
		0x04, 0x00, // Length (always 4 bytes for this type)
	)

	out := []byte{
		// EFI variable attributes
		defaultAttrsByte0, 0x00, 0x00, 0x00,

		// EFI_LOAD_OPTION.Attributes (only LOAD_OPTION_ACTIVE)
		0x01, 0x00, 0x00, 0x00,
	}

	// EFI_LOAD_OPTION.FilePathListLength
	if len(dp) > math.MaxUint16 {
		// No need to also check for overflows for Path length field explicitly,
		// since if that overflows, this field will definitely overflow as well.
		// There is no explicit length field for Description, so no special
		// handling is required.
		return nil, fmt.Errorf("variable too large, use shorter strings")
	}
	out = append16(out, uint16(len(dp)))

	// EFI_LOAD_OPTION.Description
	desc, _, e := transform.Bytes(enc, []byte(t.Description))
	if e != nil {
		return nil, fmt.Errorf("while encoding Description: %v", e)
	}
	desc = append16(desc, 0) // null terminate string
	out = append(out, desc...)

	// EFI_LOAD_OPTION.FilePathList
	out = append(out, dp...)

	// EFI_LOAD_OPTION.OptionalData is always empty

	return out, nil
}

// UnmarshalBootEntry loads a BootEntry from its binary representation.
// WARNING: UnmarshalBootEntry only loads the Description field.
// Everything else is ignored (and not validated if possible)
func UnmarshalBootEntry(d []byte) (*BootEntry, error) {
	descOffset := 4 /* EFI Var Attrs */ + 4 /* EFI_LOAD_OPTION.Attributes */ + 2 /*FilePathListLength*/
	if len(d) < descOffset {
		return nil, fmt.Errorf("too short: %v bytes", len(d))
	}
	descBytes := []byte{}
	var foundNull bool
	for i := descOffset; i+1 < len(d); i += 2 {
		a := d[i]
		b := d[i+1]
		if a == 0 && b == 0 {
			foundNull = true
			break
		}
		descBytes = append(descBytes, a, b)
	}
	if !foundNull {
		return nil, fmt.Errorf("didn't find null terminator for Description")
	}
	descDecoded, _, e := transform.Bytes(Encoding.NewDecoder(), descBytes)
	if e != nil {
		return nil, fmt.Errorf("while decoding Description: %v", e)
	}
	return &BootEntry{Description: string(descDecoded)}, nil
}

// BootOrder represents the contents of the BootOrder EFI variable.
type BootOrder []uint16

// Marshal generates the binary representation of a BootOrder.
func (t *BootOrder) Marshal() []byte {
	out := []byte{defaultAttrsByte0, 0x00, 0x00, 0x00}
	for _, v := range *t {
		out = append16(out, v)
	}
	return out
}

// UnmarshalBootOrder loads a BootOrder from its binary representation.
func UnmarshalBootOrder(d []byte) (*BootOrder, error) {
	if len(d) < 4 || len(d)%2 != 0 {
		return nil, fmt.Errorf("invalid length: %v bytes", len(d))
	}
	l := (len(d) - 4) / 2
	out := make(BootOrder, l)
	for i := 0; i < l; i++ {
		out[i] = uint16(d[4+2*i]) | uint16(d[4+2*i+1])<<8
	}
	return &out, nil
}

func append16(d []byte, v uint16) []byte {
	return append(d,
		byte(v&0xFF),
		byte(v>>8&0xFF),
	)
}

func append32(d []byte, v uint32) []byte {
	return append(d,
		byte(v&0xFF),
		byte(v>>8&0xFF),
		byte(v>>16&0xFF),
		byte(v>>24&0xFF),
	)
}

func append64(d []byte, v uint64) []byte {
	return append(d,
		byte(v&0xFF),
		byte(v>>8&0xFF),
		byte(v>>16&0xFF),
		byte(v>>24&0xFF),
		byte(v>>32&0xFF),
		byte(v>>40&0xFF),
		byte(v>>48&0xFF),
		byte(v>>56&0xFF),
	)
}
