package provision

import (
	"os"
	"strings"
	"testing"
)

// TestRealCloudInitTemplate ensures the shipped infra/cloud-init/node.yaml.tmpl
// stays a valid Go template and renders the bootstrap token + node identity.
func TestRealCloudInitTemplate(t *testing.T) {
	const path = "../../../infra/cloud-init/node.yaml.tmpl"
	if _, err := os.Stat(path); err != nil {
		t.Skipf("template not found at %s: %v", path, err)
	}
	r, err := NewTemplateRenderer(path)
	if err != nil {
		t.Fatalf("parse real template: %v", err)
	}
	out, err := r.Render(CloudInitData{
		NodeUUID:        "11111111-2222-4333-8444-555555555555",
		BootstrapToken:  "deadbeef",
		Region:          "hkg",
		Role:            RoleEntry,
		Tier:            TierFree,
		ControlPlaneURL: "https://cp.example",
	})
	if err != nil {
		t.Fatalf("render real template: %v", err)
	}
	for _, want := range []string{
		"PANGOLIN_NODE_UUID=11111111-2222-4333-8444-555555555555",
		"PANGOLIN_BOOTSTRAP_TOKEN=deadbeef",
		"PANGOLIN_CONTROL_PLANE_URL=https://cp.example",
		"#cloud-config",
	} {
		if !strings.Contains(out, want) {
			t.Errorf("rendered cloud-init missing %q", want)
		}
	}
}

func TestNewUUID_Format(t *testing.T) {
	u, err := newUUID()
	if err != nil {
		t.Fatalf("newUUID: %v", err)
	}
	if len(u) != 36 || strings.Count(u, "-") != 4 {
		t.Errorf("uuid format wrong: %q", u)
	}
	if u[14] != '4' {
		t.Errorf("not a v4 uuid: %q", u)
	}
	u2, _ := newUUID()
	if u == u2 {
		t.Error("uuid not unique")
	}
}

func TestTemplateRenderer(t *testing.T) {
	r, err := NewTemplateRendererFromString("id={{.NodeUUID}}\ntoken={{.BootstrapToken}}\ncp={{.ControlPlaneURL}}")
	if err != nil {
		t.Fatalf("parse: %v", err)
	}
	out, err := r.Render(CloudInitData{NodeUUID: "abc", BootstrapToken: "tok", ControlPlaneURL: "https://cp"})
	if err != nil {
		t.Fatalf("render: %v", err)
	}
	for _, want := range []string{"id=abc", "token=tok", "cp=https://cp"} {
		if !strings.Contains(out, want) {
			t.Errorf("rendered output missing %q:\n%s", want, out)
		}
	}
}

func TestTemplateRenderer_MissingKeyErrors(t *testing.T) {
	r, err := NewTemplateRendererFromString("{{.NoSuchField}}")
	if err != nil {
		t.Fatalf("parse: %v", err)
	}
	if _, err := r.Render(CloudInitData{}); err == nil {
		t.Error("expected error for missing template key")
	}
}
