package builder

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

func TestSafePathUnderRootAllowsNormalFile(t *testing.T) {
	root := t.TempDir()
	if err := os.WriteFile(filepath.Join(root, "readme.txt"), []byte("ok"), 0644); err != nil {
		t.Fatal(err)
	}
	got, err := safePathUnderRoot(root, "readme.txt")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if _, err := os.Stat(got); err != nil {
		t.Fatalf("resolved path missing: %v", err)
	}
}

func TestSafePathUnderRootRejectsTraversal(t *testing.T) {
	root := t.TempDir()
	cases := []string{"../secret.txt", "..", "..\\windows\\system32", "foo/../../etc/passwd"}
	for _, name := range cases {
		if _, err := safePathUnderRoot(root, name); err == nil {
			t.Fatalf("expected rejection for %q", name)
		}
	}
}

func TestSafePathUnderRootRejectsEscapeViaJoin(t *testing.T) {
	root := t.TempDir()
	secret := filepath.Join(filepath.Dir(root), "outside-secret.txt")
	if err := os.WriteFile(secret, []byte("nope"), 0644); err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { _ = os.Remove(secret) })

	// Even if file exists outside root, traversal must fail.
	if _, err := safePathUnderRoot(root, ".."+string(os.PathSeparator)+"outside-secret.txt"); err == nil {
		t.Fatal("expected path escape to be rejected")
	}
}

func TestSanitizeFileNameStripsBadChars(t *testing.T) {
	got := sanitizeFileName(`bad/name<>|?.exe`)
	if got == "" || got == `bad/name<>|?.exe` {
		t.Fatalf("sanitize did not clean name: %q", got)
	}
}
