// 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.

package main

// mkimage is a tool to generate a Metropolis node disk image containing the
// given EFI payload, and optionally, a given external initramfs image and
// node parameters

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"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"
)

var NodeDataPartition gpt.Type = gpt.Type("9eeec464-6885-414a-b278-4305c51f7966")
var NodeSystemPartition gpt.Type = gpt.Type("ee96055b-f6d0-4267-8bbb-724b2afea74c")

var (
	flagEFI                 string
	flagOut                 string
	flagSystemPath          string
	flagNodeParameters      string
	flagDataPartitionSize   uint64
	flagESPPartitionSize    uint64
	flagSystemPartitionSize uint64
)

func mibToSectors(size uint64) uint64 {
	return (size * 1024 * 1024) / 512
}

type devZeroReader struct{}

func (_ devZeroReader) Read(b []byte) (n int, err error) {
	for i := range b {
		b[i] = 0
	}
	return len(b), nil
}

// devZero is a /dev/zero-like reader which reads an infinite number of zeroes
var devZero = devZeroReader{}

func main() {
	flag.StringVar(&flagEFI, "efi", "", "UEFI payload")
	flag.StringVar(&flagOut, "out", "", "Output disk image")
	flag.StringVar(&flagSystemPath, "system", "", "System partition [optional]")
	flag.StringVar(&flagNodeParameters, "node_parameters", "", "Node parameters [optional]")
	flag.Uint64Var(&flagDataPartitionSize, "data_partition_size", 2048, "Override the data partition size (default 2048 MiB)")
	flag.Uint64Var(&flagESPPartitionSize, "esp_partition_size", 128, "Override the ESP partition size (default: 128MiB)")
	flag.Uint64Var(&flagSystemPartitionSize, "system_partition_size", 1024, "Override the System partition size (default: 1024MiB)")
	flag.Parse()

	if flagEFI == "" || flagOut == "" {
		log.Fatalf("efi and initramfs must be set")
	}

	_ = os.Remove(flagOut)
	diskImg, err := diskfs.Create(flagOut, 4*1024*1024*1024, diskfs.Raw)
	if err != nil {
		log.Fatalf("diskfs.Create(%q): %v", flagOut, err)
	}

	table := &gpt.Table{
		// This is appropriate at least for virtio disks. Might need to be adjusted for real ones.
		LogicalSectorSize:  512,
		PhysicalSectorSize: 512,
		ProtectiveMBR:      true,
		Partitions: []*gpt.Partition{
			{
				Type:  gpt.EFISystemPartition,
				Name:  "ESP",
				Start: mibToSectors(1),
				End:   mibToSectors(flagESPPartitionSize) - 1,
			},
			{
				Type:  NodeSystemPartition,
				Name:  "METROPOLIS-SYSTEM",
				Start: mibToSectors(flagESPPartitionSize),
				End:   mibToSectors(flagESPPartitionSize+flagSystemPartitionSize) - 1,
			},
			{
				Type:  NodeDataPartition,
				Name:  "METROPOLIS-NODE-DATA",
				Start: mibToSectors(flagESPPartitionSize + flagSystemPartitionSize),
				End:   mibToSectors(flagESPPartitionSize+flagSystemPartitionSize+flagDataPartitionSize) - 1,
			},
		},
	}
	if err := diskImg.Partition(table); err != nil {
		log.Fatalf("Failed to apply partition table: %v", err)
	}

	if flagSystemPath != "" {
		systemPart, err := os.Open(flagSystemPath)
		if err != nil {
			log.Fatalf("Failed to open system partition: %v", err)
		}
		defer systemPart.Close()
		systemPartMeta, err := systemPart.Stat()
		if err != nil {
			log.Fatalf("Failed to stat system partition: %v", err)
		}
		padding := int64(flagSystemPartitionSize*1024*1024) - systemPartMeta.Size()
		systemPartMulti := io.MultiReader(systemPart, io.LimitReader(devZero, padding))
		if _, err := diskImg.WritePartitionContents(2, systemPartMulti); err != nil {
			log.Fatalf("Failed to write system partition: %v", err)
		}
	}

	fs, err := diskImg.CreateFilesystem(disk.FilesystemSpec{Partition: 1, FSType: filesystem.TypeFat32, VolumeLabel: "ESP"})
	if err != nil {
		log.Fatalf("Failed to create filesystem: %v", err)
	}

	// Create EFI partition structure.
	for _, dir := range []string{"/EFI", "/EFI/BOOT", "/EFI/metropolis"} {
		if err := fs.Mkdir(dir); err != nil {
			log.Fatalf("Mkdir(%q): %v", dir, err)
		}
	}

	put(fs, flagEFI, "/EFI/BOOT/BOOTX64.EFI")

	if flagNodeParameters != "" {
		put(fs, flagNodeParameters, "/EFI/metropolis/parameters.pb")
	}

	if err := diskImg.File.Close(); err != nil {
		log.Fatalf("Failed to finalize image: %v", err)
	}
	log.Printf("Success! You can now boot %v", flagOut)
}

// put copies a file from the host filesystem into the target image.
func put(fs filesystem.FileSystem, src, dst string) {
	target, err := fs.OpenFile(dst, os.O_CREATE|os.O_RDWR)
	if err != nil {
		log.Fatalf("fs.OpenFile(%q): %v", dst, err)
	}
	source, err := os.Open(src)
	if err != nil {
		log.Fatalf("os.Open(%q): %v", src, err)
	}
	defer source.Close()
	// If this is streamed (e.g. using io.Copy) it exposes a bug in diskfs, so do it in one go.
	data, err := ioutil.ReadAll(source)
	if err != nil {
		log.Fatalf("Reading %q: %v", src, err)
	}
	if _, err := target.Write(data); err != nil {
		fmt.Printf("writing file %q: %v", dst, err)
		os.Exit(1)
	}
}
