package config

import (
	"testing"

	"metis/pkg/inventory"
)

func TestBuildUsesNodeOverridesAndDefaultFilesystem(t *testing.T) {
	inv := inventory.Inventory{
		Classes: []inventory.NodeClass{{
			Name:          "c1",
			Arch:          "arm64",
			OS:            "linux",
			Image:         "file:///tmp/base.img",
			K3sVersion:    "v1.30.0+k3s1",
			DefaultLabels: map[string]string{"role": "worker"},
		}},
		Nodes: []inventory.NodeSpec{{
			Name:          "n1",
			Class:         "c1",
			Hostname:      "n1",
			IP:            "1.1.1.1",
			K3sRole:       "server",
			K3sVersion:    "v1.31.5+k3s1",
			SSHUser:       "atlas",
			SSHAuthorized: []string{"key"},
			LonghornDisks: []inventory.LonghornDisk{{Mountpoint: "/mnt/data", UUID: "uuid-1"}},
			USBScratch: &inventory.USBScratchDisk{
				Mountpoint:  "/mnt/scratch",
				Label:       "titan-13-scratch",
				FS:          "ext4",
				BindTargets: []string{"/var/lib/rancher", "/var/log"},
			},
		}},
	}
	cfg, err := Build(&inv, "n1")
	if err != nil {
		t.Fatalf("Build: %v", err)
	}
	if got, want := cfg.K3s.Version, "v1.31.5+k3s1"; got != want {
		t.Fatalf("k3s version = %q, want %q", got, want)
	}
	if got := cfg.Fstab[0].FS; got != "ext4" {
		t.Fatalf("expected default filesystem ext4, got %q", got)
	}
	if cfg.USBScratch == nil || cfg.USBScratch.Label != "titan-13-scratch" {
		t.Fatalf("usb scratch missing: %#v", cfg.USBScratch)
	}
	if got := len(cfg.Fstab); got != 4 {
		t.Fatalf("expected longhorn plus scratch fstab entries, got %d", got)
	}
	if got := cfg.Fstab[1].Label; got != "titan-13-scratch" {
		t.Fatalf("usb scratch label = %q", got)
	}
	if got := cfg.Fstab[2].Source; got != "/mnt/scratch" || cfg.Fstab[2].Mountpoint != "/var/lib/rancher" {
		t.Fatalf("usb bind mount = %#v", cfg.Fstab[2])
	}
	if got := cfg.Labels["role"]; got != "worker" {
		t.Fatalf("label merge lost default label: %q", got)
	}
	if cfg.K3s.Role != "server" {
		t.Fatalf("expected server role, got %q", cfg.K3s.Role)
	}
}

func TestBuildReturnsErrorForMissingNode(t *testing.T) {
	inv := inventory.Inventory{}
	if _, err := Build(&inv, "missing"); err == nil {
		t.Fatal("expected missing node error")
	}
}
