package database

import (
	"context"
	"errors"
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/store/content"
	"gorm.io/gorm"
)

func TestTiDBContentAuthorityActivationGenerationCASHasOneWinner(t *testing.T) {
	db := openTiDBTestDB(t, func(db *gorm.DB) error {
		return db.AutoMigrate(&content.Authority{})
	})
	sqlDB, err := db.DB()
	require.NoError(t, err)
	sqlDB.SetMaxOpenConns(8)
	sqlDB.SetMaxIdleConns(8)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	now := time.Date(2026, 8, 21, 14, 0, 0, 0, time.UTC)
	require.NoError(t, db.Create(&content.Authority{
		ID: "cta_1", WorkspaceID: "wsp_1", Domain: "role", BindingKey: "rol_1",
		State: content.AuthorityStateLegacyActive, Generation: 1,
		UpdatedBy: "seed", CreatedAt: now, UpdatedAt: now,
	}).Error)

	store := content.New(db)
	start := make(chan struct{})
	results := make(chan error, 2)
	var ready sync.WaitGroup
	ready.Add(2)
	for i := 0; i < 2; i++ {
		go func() {
			ready.Done()
			<-start
			_, activateErr := store.ActivateNativeAuthority(ctx, content.ActivateNativeAuthorityParams{
				WorkspaceID: "wsp_1", Domain: "role", BindingKey: "rol_1", ExpectedGeneration: 1,
				Checkpoint: "import:final", Actor: "operator", Now: now.Add(time.Second),
			})
			results <- activateErr
		}()
	}
	ready.Wait()
	close(start)

	first, second := <-results, <-results
	require.True(t, (first == nil) != (second == nil), "exactly one activation must win: %v / %v", first, second)
	loser := first
	if loser == nil {
		loser = second
	}
	require.True(t, errors.Is(loser, content.ErrAuthorityConflict), loser)

	exact, found, err := store.GetAuthority(ctx, "wsp_1", "role", "rol_1")
	require.NoError(t, err)
	require.True(t, found)
	require.Equal(t, content.AuthorityStateNativeActive, exact.State)
	require.Equal(t, uint64(2), exact.Generation)
}
