//go:build integration

package git_test

import (
	"context"
	"io"
	"log/slog"
	"os"
	"os/exec"
	"path/filepath"
	"testing"

	"bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/config"
	"bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/git"
)

func TestProvider_LocalBareRepo(t *testing.T) {
	if _, err := exec.LookPath("git"); err != nil {
		t.Skip("git not available")
	}

	bareDir := t.TempDir()
	workDir := t.TempDir()
	workspace := t.TempDir()
	cloneDir := filepath.Join(workspace, "repo")

	runGit := func(dir string, args ...string) {
		t.Helper()
		cmd := exec.Command("git", args...)
		cmd.Dir = dir
		cmd.Env = append(os.Environ(), "GIT_AUTHOR_NAME=test", "GIT_AUTHOR_EMAIL=test@example.com", "GIT_COMMITTER_NAME=test", "GIT_COMMITTER_EMAIL=test@example.com")
		out, err := cmd.CombinedOutput()
		if err != nil {
			t.Fatalf("git %v in %s: %v\n%s", args, dir, err, out)
		}
	}

	runGit("", "init", "--bare", bareDir)
	runGit(workDir, "init")
	runGit(workDir, "remote", "add", "origin", bareDir)
	writeFile(t, filepath.Join(workDir, "main.go"), "package main\n")
	runGit(workDir, "add", "main.go")
	runGit(workDir, "commit", "-m", "initial")
	runGit(workDir, "branch", "-M", "main")
	runGit(workDir, "push", "-u", "origin", "main")

	writeFile(t, filepath.Join(workDir, "README.md"), "# test\n")
	runGit(workDir, "add", "README.md")
	runGit(workDir, "commit", "-m", "add readme")
	runGit(workDir, "push", "origin", "main")

	cfg := config.Config{
		Environment: "local",
		Git:         config.GitConfig{WorkspacePath: workspace},
		Bitbucket: config.BitbucketConfig{
			BaseURL: "file://" + bareDir,
		},
	}

	// Override clone URL by using file:// bare repo directly in provider test via custom runner is complex.
	// Instead test runner + classify against real git in workspace.
	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
	runner, err := git.NewShellRunner(cfg, logger)
	if err != nil {
		t.Fatalf("NewShellRunner: %v", err)
	}

	repoPath := cloneDir
	cmd := exec.Command("git", "clone", bareDir, repoPath)
	if out, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("clone: %v\n%s", err, out)
	}

	out, _, err := runner.Run(context.Background(), repoPath, "rev-parse", "HEAD")
	if err != nil {
		t.Fatalf("rev-parse: %v", err)
	}
	if out == "" {
		t.Fatal("expected HEAD sha")
	}
}

func writeFile(t *testing.T, path, content string) {
	t.Helper()
	if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
		t.Fatalf("write file: %v", err)
	}
}
