package inventory

import (
	"os"
	"path/filepath"
	"testing"
)

func TestLoadExpandsEnvironmentVariables(t *testing.T) {
	t.Setenv("METIS_IMAGE_PATH", "file:///tmp/rpi4.img")
	t.Setenv("METIS_K3S_TOKEN", "secret-token")
	t.Setenv("METIS_USB_MOUNT", "/mnt/usb")
	t.Setenv("METIS_USB_LABEL", "titan-13-scratch")
	t.Setenv("METIS_USB_BIND", "/var/lib/rancher")
	invPath := filepath.Join(t.TempDir(), "inventory.yaml")
	if err := os.WriteFile(invPath, []byte(`
classes:
  - name: rpi4
    image: ${METIS_IMAGE_PATH}
    k3s_version: v1.31.5+k3s1
nodes:
  - name: titan-13
    class: rpi4
    hostname: titan-13
    ip: 192.168.22.41
    k3s_role: agent
    k3s_token: ${METIS_K3S_TOKEN}
    usb_scratch:
      mountpoint: ${METIS_USB_MOUNT}
      label: ${METIS_USB_LABEL}
      fs: ext4
      bind_targets:
        - ${METIS_USB_BIND}
`), 0o644); err != nil {
		t.Fatal(err)
	}

	inv, err := Load(invPath)
	if err != nil {
		t.Fatalf("Load: %v", err)
	}
	node, class, err := inv.FindNode("titan-13")
	if err != nil {
		t.Fatalf("FindNode: %v", err)
	}
	if class.Image != "file:///tmp/rpi4.img" {
		t.Fatalf("image not expanded: %q", class.Image)
	}
	if node.K3sToken != "secret-token" {
		t.Fatalf("token not expanded: %q", node.K3sToken)
	}
	if node.USBScratch == nil || node.USBScratch.Mountpoint != "/mnt/usb" || node.USBScratch.Label != "titan-13-scratch" {
		t.Fatalf("usb scratch not expanded: %#v", node.USBScratch)
	}
	if len(node.USBScratch.BindTargets) != 1 || node.USBScratch.BindTargets[0] != "/var/lib/rancher" {
		t.Fatalf("usb bind target not expanded: %#v", node.USBScratch.BindTargets)
	}
}

func TestFindNodeReturnsClassMissingError(t *testing.T) {
	inv := &Inventory{
		Nodes: []NodeSpec{{Name: "n1", Class: "missing"}},
	}
	node, class, err := inv.FindNode("n1")
	if err == nil {
		t.Fatal("expected class missing error")
	}
	if node == nil || class != nil {
		t.Fatalf("unexpected node/class: %#v %#v", node, class)
	}
}

func TestLoadRejectsInvalidYAML(t *testing.T) {
	invPath := filepath.Join(t.TempDir(), "inventory.yaml")
	if err := os.WriteFile(invPath, []byte("classes: ["), 0o644); err != nil {
		t.Fatal(err)
	}
	if _, err := Load(invPath); err == nil {
		t.Fatal("expected parse inventory error")
	}
}
