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

// mkimage is a tool to generate node disk images.
// It can be used both to initialize block devices and to create image
// files.
//
// The tool takes a path to an EFI payload (--efi), a path to a abloader
// payload (--abloader) and a path to a system image (--system) as its only
// required inputs. In addition, an output path must be supplied (--out).
// Node parameters file path (--node_parameters) may also be supplied, in
// which case the file will be copied to the EFI system partition.
// Partition sizes are fixed and may be overridden by command line flags.
package main

import (
	_ "embed"
	"flag"
	"log"
	"os"

	"source.monogon.dev/osbase/blkio"
	"source.monogon.dev/osbase/blockdev"
	"source.monogon.dev/osbase/build/mkimage/osimage"
)

func main() {
	// Fill in the image parameters based on flags.
	var (
		efiPayload      string
		systemImage     string
		abLoaderPayload string
		nodeParams      string
		outputPath      string
		diskUUID        string
		cfg             osimage.Params
	)
	flag.StringVar(&efiPayload, "efi", "", "Path to the UEFI payload used")
	flag.StringVar(&systemImage, "system", "", "Path to the system partition image used")
	flag.StringVar(&abLoaderPayload, "abloader", "", "Path to the abloader payload used")
	flag.StringVar(&nodeParams, "node_parameters", "", "Path to Node Parameters to be written to the ESP (default: don't write Node Parameters)")
	flag.StringVar(&outputPath, "out", "", "Path to the resulting disk image or block device")
	flag.Int64Var(&cfg.PartitionSize.Data, "data_partition_size", 2048, "Override the data partition size (default 2048 MiB). Used only when generating image files.")
	flag.Int64Var(&cfg.PartitionSize.ESP, "esp_partition_size", 128, "Override the ESP partition size (default: 128MiB)")
	flag.Int64Var(&cfg.PartitionSize.System, "system_partition_size", 1024, "Override the System partition size (default: 1024MiB)")
	flag.StringVar(&diskUUID, "GUID", "", "Disk GUID marked in the resulting image's partition table (default: randomly generated)")
	flag.Parse()

	// Open the input files for osimage.Create, fill in reader objects and
	// metadata in osimage.Params.
	// Start with the EFI Payload the OS will boot from.
	p, err := blkio.NewFileReader(efiPayload)
	if err != nil {
		log.Fatalf("while opening the EFI payload at %q: %v", efiPayload, err)
	}
	cfg.EFIPayload = p

	ab, err := blkio.NewFileReader(abLoaderPayload)
	if err != nil {
		log.Fatalf("while opening the abloader payload at %q: %v", abLoaderPayload, err)
	}
	cfg.ABLoader = ab

	// Attempt to open the system image if its path is set. In case the path
	// isn't set, the system partition will still be created, but no
	// contents will be written into it.
	if systemImage != "" {
		img, err := os.Open(systemImage)
		if err != nil {
			log.Fatalf("while opening the system image at %q: %v", systemImage, err)
		}
		defer img.Close()
		cfg.SystemImage = img
	}

	// Attempt to open the node parameters file if its path is set.
	if nodeParams != "" {
		np, err := blkio.NewFileReader(nodeParams)
		if err != nil {
			log.Fatalf("while opening node parameters at %q: %v", nodeParams, err)
		}
		cfg.NodeParameters = np
	}

	// TODO(#254): Build and use dynamically-grown block devices
	cfg.Output, err = blockdev.CreateFile(outputPath, 512, 10*1024*1024)
	if err != nil {
		panic(err)
	}

	// Write the parametrized OS image.
	if _, err := osimage.Write(&cfg); err != nil {
		log.Fatalf("while creating a Metropolis OS image: %v", err)
	}
}
