// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This package provides self-contained implementation used to generate
// Metropolis disk images.
package osimage

import (
	"fmt"
	"io"
	"os"

	diskfs "github.com/diskfs/go-diskfs"
	"github.com/diskfs/go-diskfs/disk"
	"github.com/diskfs/go-diskfs/filesystem"
	"github.com/diskfs/go-diskfs/partition/gpt"
	"github.com/google/uuid"

	"source.monogon.dev/metropolis/pkg/efivarfs"
)

const (
	systemPartitionType = gpt.Type("ee96055b-f6d0-4267-8bbb-724b2afea74c")
	SystemVolumeLabel   = "METROPOLIS-SYSTEM"

	dataPartitionType = gpt.Type("9eeec464-6885-414a-b278-4305c51f7966")
	DataVolumeLabel   = "METROPOLIS-NODE-DATA"

	ESPVolumeLabel = "ESP"

	EFIPayloadPath = "/EFI/BOOT/BOOTx64.EFI"
	nodeParamsPath = "/metropolis/parameters.pb"

	mib = 1024 * 1024
)

// put creates a file on the target filesystem fs and fills it with
// contents read from an io.Reader object src.
func put(fs filesystem.FileSystem, dst string, src io.Reader) error {
	target, err := fs.OpenFile(dst, os.O_CREATE|os.O_RDWR)
	if err != nil {
		return fmt.Errorf("while opening %q: %w", dst, err)
	}

	// If this is streamed (e.g. using io.Copy) it exposes a bug in diskfs, so
	// do it in one go.
	// TODO(mateusz@monogon.tech): Investigate the bug.
	data, err := io.ReadAll(src)
	if err != nil {
		return fmt.Errorf("while reading %q: %w", src, err)
	}
	if _, err := target.Write(data); err != nil {
		return fmt.Errorf("while writing to %q: %w", dst, err)
	}
	return nil
}

// initializeESP creates an ESP filesystem in a partition specified by
// index. It then creates the EFI executable and copies into it contents
// of the reader object exec, which must not be nil. The node parameters
// file is optionally created if params is not nil. initializeESP may return
// an error.
func initializeESP(image *disk.Disk, index int, exec, params io.Reader) error {
	// Create a FAT ESP filesystem inside a partition pointed to by
	// index.
	spec := disk.FilesystemSpec{
		Partition:   index,
		FSType:      filesystem.TypeFat32,
		VolumeLabel: ESPVolumeLabel,
	}
	fs, err := image.CreateFilesystem(spec)
	if err != nil {
		return fmt.Errorf("while creating an ESP filesystem: %w", err)
	}

	// Create the EFI partition structure.
	for _, dir := range []string{"/EFI", "/EFI/BOOT", "/metropolis"} {
		if err := fs.Mkdir(dir); err != nil {
			return fmt.Errorf("while creating %q: %w", dir, err)
		}
	}

	// Copy the EFI payload to the newly created filesystem.
	if exec == nil {
		return fmt.Errorf("exec must not be nil")
	}
	if err := put(fs, EFIPayloadPath, exec); err != nil {
		return fmt.Errorf("while writing an EFI payload: %w", err)
	}

	if params != nil {
		// Copy Node Parameters into the ESP.
		if err := put(fs, nodeParamsPath, params); err != nil {
			return fmt.Errorf("while writing node parameters: %w", err)
		}
	}
	return nil
}

// zeroSrc is a source of null bytes implementing io.Reader. It acts as a
// helper data type.
type zeroSrc struct{}

// Read implements io.Reader for zeroSrc. It fills b with zero bytes. The
// returned error is always nil.
func (_ zeroSrc) Read(b []byte) (n int, err error) {
	for i := range b {
		b[i] = 0
	}
	return len(b), nil
}

// initializeSystemPartition copies system partition contents into a partition
// at index. The remaining partition space is zero-padded. This function may
// return an error.
func initializeSystemPartition(image *disk.Disk, index int, contents io.Reader) error {
	// Check the parameters.
	if contents == nil {
		return fmt.Errorf("system partition contents parameter must not be nil")
	}
	if index <= 0 {
		return fmt.Errorf("partition index must be greater than zero")
	}

	// Get the system partition's size.
	table, err := image.GetPartitionTable()
	if err != nil {
		return fmt.Errorf("while accessing a go-diskfs partition table: %w", err)
	}
	partitions := table.GetPartitions()
	if index > len(partitions) {
		return fmt.Errorf("partition index out of bounds")
	}
	size := partitions[index-1].GetSize()

	// Copy the contents of the Metropolis system image into the system partition
	// at partitionIndex. Zero-pad the remaining space.
	var zero zeroSrc
	sys := io.LimitReader(io.MultiReader(contents, zero), size)
	if _, err := image.WritePartitionContents(index, sys); err != nil {
		return fmt.Errorf("while copying the system partition: %w", err)
	}
	return nil
}

// mibToSectors converts a size expressed in mebibytes to a number of
// sectors needed to store data of that size. sectorSize parameter
// specifies the size of a logical sector.
func mibToSectors(size, sectorSize uint64) uint64 {
	return (size * mib) / sectorSize
}

// PartitionSizeInfo contains parameters used during partition table
// initialization and, in case of image files, space allocation.
type PartitionSizeInfo struct {
	// Size of the EFI System Partition (ESP), in mebibytes. The size must
	// not be zero.
	ESP uint64
	// Size of the Metropolis system partition, in mebibytes. The partition
	// won't be created if the size is zero.
	System uint64
	// Size of the Metropolis data partition, in mebibytes. The partition
	// won't be created if the size is zero. If the image is output to a
	// block device, the partition will be extended to fill the remaining
	// space.
	Data uint64
}

// partitionList stores partition definitions in an ascending order.
type partitionList []*gpt.Partition

// appendPartition puts a new partition at the end of a partitionList,
// automatically calculating its start and end markers based on data in
// the list and the argument psize. A partition type and a name are
// assigned to the partition. The containing image is used to calculate
// sector addresses based on its logical block size.
func (pl *partitionList) appendPartition(image *disk.Disk, ptype gpt.Type, pname string, psize uint64) {
	// Calculate the start and end marker.
	var pstart, pend uint64
	if len(*pl) != 0 {
		pstart = (*pl)[len(*pl)-1].End + 1
	} else {
		pstart = mibToSectors(1, uint64(image.LogicalBlocksize))
	}
	pend = pstart + mibToSectors(psize, uint64(image.LogicalBlocksize)) - 1

	// Put the new partition at the end of the list.
	*pl = append(*pl, &gpt.Partition{
		Type:  ptype,
		Name:  pname,
		Start: pstart,
		End:   pend,
	})
}

// extendLastPartition moves the end marker of the last partition in a
// partitionList to the end of image, assigning all of the remaining free
// space to it. It may return an error.
func (pl *partitionList) extendLastPartition(image *disk.Disk) error {
	if len(*pl) == 0 {
		return fmt.Errorf("no partitions defined")
	}
	if image.Size == 0 {
		return fmt.Errorf("the image size mustn't be zero")
	}
	if image.LogicalBlocksize == 0 {
		return fmt.Errorf("the image's logical block size mustn't be zero")
	}

	// The last 33 blocks are occupied by the Secondary GPT.
	(*pl)[len(*pl)-1].End = uint64(image.Size/image.LogicalBlocksize) - 33
	return nil
}

// initializePartitionTable applies a Metropolis-compatible GPT partition
// table to an image. Logical and physical sector sizes are based on
// block sizes exposed by Disk. Partition extents are defined by the size
// argument. A diskGUID is associated with the partition table. In an event
// the table couldn't have been applied, the function will return an error.
func initializePartitionTable(image *disk.Disk, size *PartitionSizeInfo, diskGUID string) error {
	// Start with preparing a partition list.
	var pl partitionList
	// Create the ESP.
	if size.ESP == 0 {
		return fmt.Errorf("ESP size mustn't be zero")
	}
	pl.appendPartition(image, gpt.EFISystemPartition, ESPVolumeLabel, size.ESP)
	// Create the system partition only if its size is specified.
	if size.System != 0 {
		pl.appendPartition(image, systemPartitionType, SystemVolumeLabel, size.System)
	}
	// Create the data partition only if its size is specified.
	if size.Data != 0 {
		// Don't specify the last partition's length, as it will be extended
		// to fit the image size anyway. size.Data will still be used in the
		// space allocation step.
		pl.appendPartition(image, dataPartitionType, DataVolumeLabel, 0)
		if err := pl.extendLastPartition(image); err != nil {
			return fmt.Errorf("while extending the last partition: %w", err)
		}
	}

	// Build and apply the partition table.
	table := &gpt.Table{
		LogicalSectorSize:  int(image.LogicalBlocksize),
		PhysicalSectorSize: int(image.PhysicalBlocksize),
		ProtectiveMBR:      true,
		GUID:               diskGUID,
		Partitions:         pl,
	}
	if err := image.Partition(table); err != nil {
		// Return the error unwrapped.
		return err
	}
	return nil
}

// Params contains parameters used by Create to build a Metropolis OS
// image.
type Params struct {
	// OutputPath is the path an OS image will be written to. If the path
	// points to an existing block device, the data partition will be
	// extended to fill it entirely. Otherwise, a regular image file will
	// be created at OutputPath. The path must not point to an existing
	// regular file.
	OutputPath string
	// EFIPayload provides contents of the EFI payload file. It must not be
	// nil.
	EFIPayload io.Reader
	// SystemImage provides contents of the Metropolis system partition.
	// If nil, no contents will be copied into the partition.
	SystemImage io.Reader
	// NodeParameters provides contents of the node parameters file. If nil,
	// the node parameters file won't be created in the target ESP
	// filesystem.
	NodeParameters io.Reader
	// DiskGUID is a unique identifier of the image and a part of GPT
	// header. It's optional and can be left blank if the identifier is
	// to be randomly generated. Setting it to a predetermined value can
	// help in implementing reproducible builds.
	DiskGUID string
	// PartitionSize specifies a size for the ESP, Metropolis System and
	// Metropolis data partition.
	PartitionSize PartitionSizeInfo
}

// Create writes a Metropolis OS image to either a newly created regular
// file or a block device. The image is parametrized by the params
// argument. In case a regular file already exists at params.OutputPath,
// the function will fail. It returns nil on success or an error, if one
// did occur.
func Create(params *Params) (*efivarfs.BootEntry, error) {
	// Validate each parameter before use.
	if params.OutputPath == "" {
		return nil, fmt.Errorf("image output path must be set")
	}

	// Learn whether we're creating a new image or writing to an existing
	// block device by stat-ing the output path parameter.
	outInfo, err := os.Stat(params.OutputPath)
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}

	// Calculate the image size (bytes) by summing up partition sizes
	// (mebibytes).
	minSize := (int64(params.PartitionSize.ESP) +
		int64(params.PartitionSize.System) +
		int64(params.PartitionSize.Data) + 1) * mib
	var diskImg *disk.Disk
	if !os.IsNotExist(err) && outInfo.Mode()&os.ModeDevice != 0 {
		// Open the block device. The data partition size parameter won't
		// matter in this case, as said partition will be extended till the
		// end of device.
		diskImg, err = diskfs.Open(params.OutputPath)
		if err != nil {
			return nil, fmt.Errorf("couldn't open the block device at %q: %w", params.OutputPath, err)
		}
		// Make sure there's at least minSize space available on the block
		// device.
		if minSize > diskImg.Size {
			return nil, fmt.Errorf("not enough space available on the block device at %q", params.OutputPath)
		}
	} else {
		// Attempt to create an image file at params.OutputPath. diskfs.Create
		// will abort in case a file already exists at the given path.
		// Calculate the image size expressed in bytes by summing up declared
		// partition lengths.
		diskImg, err = diskfs.Create(params.OutputPath, minSize, diskfs.Raw)
		if err != nil {
			return nil, fmt.Errorf("couldn't create a disk image at %q: %w", params.OutputPath, err)
		}
	}

	// Go through the initialization steps, starting with applying a
	// partition table according to params.
	if err := initializePartitionTable(diskImg, &params.PartitionSize, params.DiskGUID); err != nil {
		return nil, fmt.Errorf("failed to initialize the partition table: %w", err)
	}
	// The system partition will be created only if its specified size isn't
	// equal to zero, making the initialization step optional as well. In
	// addition, params.SystemImage must be set.
	if params.PartitionSize.System != 0 && params.SystemImage != nil {
		if err := initializeSystemPartition(diskImg, 2, params.SystemImage); err != nil {
			return nil, fmt.Errorf("failed to initialize the system partition: %w", err)
		}
	} else if params.PartitionSize.System == 0 && params.SystemImage != nil {
		// Safeguard against contradicting parameters.
		return nil, fmt.Errorf("the system image parameter was passed while the associated partition size is zero")
	}
	// Attempt to initialize the ESP unconditionally, as it's the only
	// partition guaranteed to be created regardless of params.PartitionSize.
	if err := initializeESP(diskImg, 1, params.EFIPayload, params.NodeParameters); err != nil {
		return nil, fmt.Errorf("failed to initialize the ESP: %w", err)
	}
	// The data partition, even if created, is always left uninitialized.

	// Build an EFI boot entry pointing to the image's ESP. go-diskfs won't let
	// you do that after you close the image.
	t, err := diskImg.GetPartitionTable()
	p := t.GetPartitions()
	esp := (p[0]).(*gpt.Partition)
	guid, err := uuid.Parse(esp.GUID)
	if err != nil {
		return nil, fmt.Errorf("couldn't parse the GPT GUID: %w", err)
	}
	be := efivarfs.BootEntry{
		Description:     "Metropolis",
		Path:            EFIPayloadPath,
		PartitionGUID:   guid,
		PartitionNumber: 1,
		PartitionStart:  esp.Start,
		PartitionSize:   esp.End - esp.Start + 1,
	}
	// Close the image and return the EFI boot entry.
	if err := diskImg.File.Close(); err != nil {
		return nil, fmt.Errorf("failed to finalize image: %w", err)
	}
	return &be, nil
}
