package plan

import (
	"context"
	"fmt"
	"path/filepath"
	"strings"

	"metis/pkg/image"
	"metis/pkg/inventory"
	"metis/pkg/writer"
)

// BuildImageFile materializes a fully injected raw image for a node.
func BuildImageFile(ctx context.Context, inv *inventory.Inventory, nodeName, cacheDir, output string) error {
	p, err := Build(inv, nodeName, output, cacheDir)
	if err != nil {
		return fmt.Errorf("build plan: %w", err)
	}
	_, class, err := inv.FindNode(nodeName)
	if err != nil {
		return fmt.Errorf("load node class: %w", err)
	}

	cacheImage := filepath.Join(cacheDir, cacheName(p.Image))
	cacheImage, err = image.DownloadAndVerify(p.Image, cacheImage, class.Checksum)
	if err != nil {
		return fmt.Errorf("download image: %w", err)
	}
	if err := writer.WriteImage(ctx, cacheImage, output); err != nil {
		return fmt.Errorf("copy base image: %w", err)
	}

	files, err := Files(inv, nodeName)
	if err != nil {
		return fmt.Errorf("resolve files: %w", err)
	}
	if err := image.InjectImage(output, files); err != nil {
		return fmt.Errorf("inject image: %w", err)
	}
	return nil
}

func cacheName(source string) string {
	base := filepath.Base(source)
	return strings.TrimSuffix(base, ".xz")
}
