// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package main

import (
	"archive/zip"
	"bytes"
	_ "embed"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"

	"source.monogon.dev/go/logging"
	"source.monogon.dev/osbase/blockdev"
	"source.monogon.dev/osbase/build/mkimage/osimage"
	"source.monogon.dev/osbase/efivarfs"
)

//go:embed metropolis/node/core/abloader/abloader.efi
var abloader []byte

// FileSizedReader is a small adapter from fs.File to fs.SizedReader
// Panics on Stat() failure, so should only be used with sources where Stat()
// cannot fail.
type FileSizedReader struct {
	fs.File
}

func (f FileSizedReader) Size() int64 {
	stat, err := f.Stat()
	if err != nil {
		panic(err)
	}
	return stat.Size()
}

// EnvInstallTarget environment variable which tells the takeover binary where
// to install to
const EnvInstallTarget = "TAKEOVER_INSTALL_TARGET"

func installMetropolis(l logging.Leveled) error {
	// Validate we are running via EFI.
	if _, err := os.Stat("/sys/firmware/efi"); os.IsNotExist(err) {
		// nolint:ST1005
		return fmt.Errorf("Monogon OS can only be installed on EFI-booted machines, this one is not")
	}

	metropolisSpecRaw, err := os.ReadFile("/params.pb")
	if err != nil {
		return err
	}

	bundleRaw, err := os.Open("/bundle.zip")
	if err != nil {
		return err
	}

	bundleStat, err := bundleRaw.Stat()
	if err != nil {
		return err
	}

	bundle, err := zip.NewReader(bundleRaw, bundleStat.Size())
	if err != nil {
		return fmt.Errorf("failed to open node bundle: %w", err)
	}

	installParams, err := setupOSImageParams(bundle, metropolisSpecRaw, os.Getenv(EnvInstallTarget))
	if err != nil {
		return err
	}

	be, err := osimage.Write(installParams)
	if err != nil {
		return fmt.Errorf("failed to apply installation: %w", err)
	}
	bootEntryIdx, err := efivarfs.AddBootEntry(be)
	if err != nil {
		return fmt.Errorf("error creating EFI boot entry: %w", err)
	}
	if err := efivarfs.SetBootOrder(efivarfs.BootOrder{uint16(bootEntryIdx)}); err != nil {
		return fmt.Errorf("error setting EFI boot order: %w", err)
	}
	l.Info("Metropolis installation completed")
	return nil
}

func setupOSImageParams(bundle *zip.Reader, metropolisSpecRaw []byte, installTarget string) (*osimage.Params, error) {
	rootDev, err := blockdev.Open(filepath.Join("/dev", installTarget))
	if err != nil {
		return nil, fmt.Errorf("failed to open root device: %w", err)
	}

	efiPayload, err := bundle.Open("kernel_efi.efi")
	if err != nil {
		return nil, fmt.Errorf("invalid bundle: %w", err)
	}

	systemImage, err := bundle.Open("verity_rootfs.img")
	if err != nil {
		return nil, fmt.Errorf("invalid bundle: %w", err)
	}

	return &osimage.Params{
		PartitionSize: osimage.PartitionSizeInfo{
			ESP:    384,
			System: 4096,
			Data:   128,
		},
		SystemImage:    systemImage,
		EFIPayload:     FileSizedReader{efiPayload},
		ABLoader:       bytes.NewReader(abloader),
		NodeParameters: bytes.NewReader(metropolisSpecRaw),
		Output:         rootDev,
	}, nil
}
