package service

import (
	"context"
	"errors"
	"strings"
	"testing"

	"github.com/pingcap/agent-git-service/internal/db"
	"github.com/pingcap/agent-git-service/internal/tenant"
	"gorm.io/gorm"
)

func setupCleanupForkRepoService(t *testing.T) (*Service, *gorm.DB, context.Context, func()) {
	t.Helper()

	gdb, dbCleanup := openMigratedServiceTestDB(t)
	resources := testTenantResources(t, tenant.ID("cleanup-fork"), gdb)
	svc := mustNewTenantService(t, testTenantResourcesProvider{resources.Info.ID: resources})
	ctx := tenant.WithInfo(t.Context(), resources.Info)

	cleanup := func() {
		dbCleanup()
	}

	return svc, gdb.WithContext(ctx), ctx, cleanup
}

func TestCleanupForkRepo_ReturnsDeleteError(t *testing.T) {
	svc, database, ctx, cleanup := setupCleanupForkRepoService(t)
	defer cleanup()

	owner := db.User{Login: "cleanup-owner", Type: db.TypeUser}
	if err := database.Create(&owner).Error; err != nil {
		t.Fatalf("create owner: %v", err)
	}
	repo := db.Repository{
		Name:          "repo",
		FullName:      "cleanup-owner/repo",
		OwnerID:       owner.ID,
		DefaultBranch: "main",
	}
	if err := database.Create(&repo).Error; err != nil {
		t.Fatalf("create repo: %v", err)
	}

	const cbName = "test:cleanup_fork_repo_update_fail"
	if err := database.Callback().Update().Before("gorm:update").Register(cbName, func(tx *gorm.DB) {
		if tx.Statement.Table == "repositories" || (tx.Statement.Schema != nil && tx.Statement.Schema.Table == "repositories") {
			tx.AddError(errors.New("forced update failure"))
		}
	}); err != nil {
		t.Fatalf("register update callback: %v", err)
	}
	defer func() {
		_ = database.Callback().Update().Remove(cbName)
	}()

	err := svc.cleanupForkRepo(ctx, repo.FullName, "test")
	if err == nil {
		t.Fatal("expected cleanupForkRepo to return error")
	}
	errMsg := err.Error()
	if !strings.Contains(errMsg, "forced update failure") {
		t.Fatalf("expected delete error to be included, got: %v", err)
	}
}
