package gitmirror

import (
	"context"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

func TestMirrorWritableRefsBootstrapsAndRejectsUnexpectedTargetRef(t *testing.T) {
	root := t.TempDir()
	source := filepath.Join(root, "source")
	target := filepath.Join(root, "target.git")
	runTestGit(t, root, "init", "-b", "main", source)
	runTestGit(t, source, "config", "user.name", "Sync Test")
	runTestGit(t, source, "config", "user.email", "sync@example.test")
	if err := os.WriteFile(filepath.Join(source, "README.md"), []byte("one\n"), 0o600); err != nil {
		t.Fatal(err)
	}
	runTestGit(t, source, "add", "README.md")
	runTestGit(t, source, "commit", "-m", "initial")
	runTestGit(t, source, "branch", "feature")
	runTestGit(t, source, "tag", "v1")
	runTestGit(t, root, "init", "--bare", target)

	if err := MirrorWritableRefs(context.Background(), source, "", target, "", root); err != nil {
		t.Fatal(err)
	}
	// Retrying an already-complete bootstrap is a no-op, which is required
	// after a worker crash between Git push and per-RunItem verification.
	if err := MirrorWritableRefs(context.Background(), source, "", target, "", root); err != nil {
		t.Fatal(err)
	}
	refs := runTestGit(t, root, "ls-remote", "--heads", "--tags", target)
	for _, name := range []string{"refs/heads/main", "refs/heads/feature", "refs/tags/v1"} {
		if !strings.Contains(refs, name) {
			t.Fatalf("target refs missing %s:\n%s", name, refs)
		}
	}

	runTestGit(t, source, "push", target, "HEAD:refs/heads/unmanaged")
	if err := MirrorWritableRefs(context.Background(), source, "", target, "", root); err == nil {
		t.Fatal("bootstrap accepted a target-only unmanaged ref")
	}
}

func runTestGit(t *testing.T, dir string, args ...string) string {
	t.Helper()
	command := exec.Command("git", args...)
	command.Dir = dir
	output, err := command.CombinedOutput()
	if err != nil {
		t.Fatalf("git %s: %v: %s", strings.Join(args, " "), err, output)
	}
	return string(output)
}
