package testing_test

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

func TestPlanCLIProducesActions(t *testing.T) {
	root := repoRoot(t)
	dummy := filepath.Join(t.TempDir(), "dummy.img")
	if err := os.WriteFile(dummy, []byte("dummy"), 0o644); err != nil {
		t.Fatal(err)
	}
	checksum := sha256.Sum256(readFile(t, dummy))
	invPath := filepath.Join(t.TempDir(), "inv.yaml")
	inv := fmt.Sprintf(`{
  "classes": [
    {
      "name": "test-class",
      "arch": "arm64",
      "os": "testos",
      "image": "file://%s",
      "checksum": "sha256:%s",
      "default_labels": {"role": "worker"}
    }
  ],
  "nodes": [
    {
      "name": "node-a",
      "class": "test-class",
      "hostname": "node-a",
      "ip": "10.0.0.10",
      "k3s_role": "agent"
    }
  ]
}`,
		dummy,
		hex.EncodeToString(checksum[:]),
	)
	if err := os.WriteFile(invPath, []byte(inv), 0o644); err != nil {
		t.Fatal(err)
	}
	cmd := exec.Command("go", "run", "./cmd/metis", "plan", "--inventory", invPath, "--node", "node-a", "--device", "/dev/sdz", "--cache", filepath.Join(t.TempDir(), "cache"))
	cmd.Dir = root
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("plan command failed: %v\n%s", err, out)
	}
	var plan struct {
		Node    string `json:"node"`
		Actions []struct {
			Type string `json:"type"`
		} `json:"actions"`
	}
	if err := json.Unmarshal(out, &plan); err != nil {
		t.Fatalf("decode plan: %v\n%s", err, out)
	}
	if plan.Node != "node-a" {
		t.Fatalf("node = %q", plan.Node)
	}
	for _, action := range plan.Actions {
		if action.Type == "fetch" {
			return
		}
	}
	t.Fatal("expected a fetch action")
}

func TestBurnDryRunPrintsPlan(t *testing.T) {
	root := repoRoot(t)
	dummy := filepath.Join(t.TempDir(), "dummy.img")
	if err := os.WriteFile(dummy, []byte("dummy"), 0o644); err != nil {
		t.Fatal(err)
	}
	checksum := sha256.Sum256(readFile(t, dummy))
	invPath := filepath.Join(t.TempDir(), "inv.yaml")
	inv := fmt.Sprintf(`{
  "classes": [
    {
      "name": "test-class",
      "arch": "arm64",
      "os": "testos",
      "image": "file://%s",
      "checksum": "sha256:%s",
      "default_labels": {"role": "worker"}
    }
  ],
  "nodes": [
    {
      "name": "node-a",
      "class": "test-class",
      "hostname": "node-a",
      "ip": "10.0.0.10",
      "k3s_role": "agent"
    }
  ]
}`,
		dummy,
		hex.EncodeToString(checksum[:]),
	)
	if err := os.WriteFile(invPath, []byte(inv), 0o644); err != nil {
		t.Fatal(err)
	}
	cmd := exec.Command("go", "run", "./cmd/metis", "burn", "--inventory", invPath, "--node", "node-a", "--device", "/dev/sdz", "--cache", filepath.Join(t.TempDir(), "cache"))
	cmd.Dir = root
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("burn command failed: %v\n%s", err, out)
	}
	got := string(out)
	if !strings.Contains(got, "Dry run") && !strings.Contains(got, "Plan for") {
		t.Fatalf("unexpected output: %s", got)
	}
}
