package infra

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

func TestAuditE2ECoverage_EmptyRoot(t *testing.T) {
	dir := t.TempDir()
	// Empty directory — no app.md files.
	report, err := AuditE2ECoverage([]string{dir})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if report.Total != 0 {
		t.Errorf("Total: got %d, want 0", report.Total)
	}
	if report.WithChecks != 0 {
		t.Errorf("WithChecks: got %d, want 0", report.WithChecks)
	}
	if report.CoveragePct != 0.0 {
		t.Errorf("CoveragePct: got %f, want 0.0", report.CoveragePct)
	}
	if len(report.Missing) != 0 {
		t.Errorf("Missing: got %v, want empty", report.Missing)
	}
}

func TestAuditE2ECoverage_AllCovered(t *testing.T) {
	dir := t.TempDir()

	apps := []struct {
		subdir  string
		content string
	}{
		{
			"apps/registry_dashboard",
			"---\nname: registry_dashboard\ne2e_checks:\n  - id: build\n    cmd: go build .\n---\n",
		},
		{
			"apps/kanban",
			"---\nname: kanban\ne2e_checks:\n  - id: tests\n    cmd: go test ./...\n---\n",
		},
	}

	for _, a := range apps {
		full := filepath.Join(dir, a.subdir)
		if err := os.MkdirAll(full, 0o755); err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(filepath.Join(full, "app.md"), []byte(a.content), 0o644); err != nil {
			t.Fatal(err)
		}
	}

	report, err := AuditE2ECoverage([]string{filepath.Join(dir, "apps")})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if report.Total != 2 {
		t.Errorf("Total: got %d, want 2", report.Total)
	}
	if report.WithChecks != 2 {
		t.Errorf("WithChecks: got %d, want 2", report.WithChecks)
	}
	if report.CoveragePct != 100.0 {
		t.Errorf("CoveragePct: got %f, want 100.0", report.CoveragePct)
	}
	if len(report.Missing) != 0 {
		t.Errorf("Missing: got %v, want empty", report.Missing)
	}
}

func TestAuditE2ECoverage_PartialCoverage(t *testing.T) {
	dir := t.TempDir()

	covered := filepath.Join(dir, "apps", "registry_dashboard")
	uncovered := filepath.Join(dir, "apps", "legacy_app")
	for _, d := range []string{covered, uncovered} {
		if err := os.MkdirAll(d, 0o755); err != nil {
			t.Fatal(err)
		}
	}

	// app.md with e2e_checks
	covContent := "---\nname: registry_dashboard\ne2e_checks:\n  - id: smoke\n    cmd: ./registry_dashboard --help\n---\n"
	if err := os.WriteFile(filepath.Join(covered, "app.md"), []byte(covContent), 0o644); err != nil {
		t.Fatal(err)
	}

	// app.md without e2e_checks
	uncovContent := "---\nname: legacy_app\ndescription: A legacy app without e2e coverage.\n---\n"
	if err := os.WriteFile(filepath.Join(uncovered, "app.md"), []byte(uncovContent), 0o644); err != nil {
		t.Fatal(err)
	}

	report, err := AuditE2ECoverage([]string{filepath.Join(dir, "apps")})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if report.Total != 2 {
		t.Errorf("Total: got %d, want 2", report.Total)
	}
	if report.WithChecks != 1 {
		t.Errorf("WithChecks: got %d, want 1", report.WithChecks)
	}
	wantPct := 50.0
	if math.Abs(report.CoveragePct-wantPct) > 0.01 {
		t.Errorf("CoveragePct: got %f, want %f", report.CoveragePct, wantPct)
	}
	if len(report.Missing) != 1 {
		t.Errorf("Missing len: got %d, want 1", len(report.Missing))
	}
}
