package im

import (
	"context"
	"strings"
)

type taskLifecycleProtectedScopesContextKey struct{}

type taskLifecycleProtectedScopes struct {
	workspaceID string
	scopeIDs    map[string]struct{}
}

// WithTaskLifecycleProtectedScopes marks the exact Task scopes whose lifecycle
// rows are held by the caller for the full duration of a nested IM append.
// Only trusted post-commit fanout code should attach this marker.
func WithTaskLifecycleProtectedScopes(ctx context.Context, workspaceID string, scopeIDs []string) context.Context {
	if ctx == nil {
		ctx = context.Background()
	}
	workspaceID = normalizedString(workspaceID)
	if workspaceID == "" {
		return ctx
	}
	normalized := make(map[string]struct{}, len(scopeIDs))
	for _, scopeID := range scopeIDs {
		if scopeID = normalizedString(scopeID); scopeID != "" {
			normalized[scopeID] = struct{}{}
		}
	}
	if len(normalized) == 0 {
		return ctx
	}
	return context.WithValue(ctx, taskLifecycleProtectedScopesContextKey{}, taskLifecycleProtectedScopes{
		workspaceID: workspaceID,
		scopeIDs:    normalized,
	})
}

func taskLifecycleScopeIsProtected(ctx context.Context, workspaceID string, scopeID string) bool {
	if ctx == nil {
		return false
	}
	protected, ok := ctx.Value(taskLifecycleProtectedScopesContextKey{}).(taskLifecycleProtectedScopes)
	if !ok || protected.workspaceID != strings.TrimSpace(workspaceID) {
		return false
	}
	_, ok = protected.scopeIDs[strings.TrimSpace(scopeID)]
	return ok
}
