package securityevents

import (
	"context"
	"errors"
	"time"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)

const (
	identitySecretCleanupInterval = time.Minute
	identitySecretCleanupLease    = 5 * time.Minute
	identitySecretCleanupBatch    = 100
)

type IdentitySecretCleanupRepository interface {
	ClaimIdentitySecretCleanups(context.Context, int, time.Duration) ([]store.IdentitySecretCleanupClaim, error)
	CompleteIdentitySecretCleanup(context.Context, string, string) (bool, error)
}

// RunIdentitySecretCleanupWorker owns cleanup at the server lifecycle rather
// than at any individual Active or Prepared identity Runtime. PostgreSQL claim
// tokens make running one worker per server replica safe.
func RunIdentitySecretCleanupWorker(ctx context.Context, repository IdentitySecretCleanupRepository, secrets SecretStore) {
	if repository == nil || secrets == nil {
		return
	}
	ticker := time.NewTicker(identitySecretCleanupInterval)
	defer ticker.Stop()
	for {
		cleanupClaimedIdentitySecrets(ctx, repository, secrets)
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
		}
	}
}

func cleanupClaimedIdentitySecrets(ctx context.Context, repository IdentitySecretCleanupRepository, secrets SecretStore) {
	claims, err := repository.ClaimIdentitySecretCleanups(ctx, identitySecretCleanupBatch, identitySecretCleanupLease)
	if err != nil {
		return
	}
	for _, claim := range claims {
		if err := secrets.Delete(ctx, claim.Reference); err != nil && !errors.Is(err, ErrSecretNotFound) {
			continue
		}
		_, _ = repository.CompleteIdentitySecretCleanup(ctx, claim.Reference, claim.ClaimToken)
	}
}
