package constants

import "context"

// SecurityContext controls which security checks are bypassed.
// Explicit values (not iota) prevent reorder bugs.
type SecurityContext int

const (
	UserContext     SecurityContext = 0  // Default. All checks enforced.
	ServiceContext  SecurityContext = 10 // Trusted service on behalf of real user.
	ElevatedContext SecurityContext = 20 // Real user identity, elevated privileges.
	SystemContext   SecurityContext = 30 // No real user. Full bypass.
)

type contextKeyType string

const (
	contextKeySecurityLevel  contextKeyType = "security_level"
	contextKeySecurityReason contextKeyType = "security_reason"
)

// BypassesProcessFields returns true for ServiceContext and above.
func (sc SecurityContext) BypassesProcessFields() bool { return sc >= ServiceContext }

// BypassesCRUDandFLS returns true for ElevatedContext and above.
func (sc SecurityContext) BypassesCRUDandFLS() bool { return sc >= ElevatedContext }

// BypassesRLS returns true for SystemContext only.
func (sc SecurityContext) BypassesRLS() bool { return sc >= SystemContext }

// WithSecurityContext sets the security context with a mandatory reason for audit.
func WithSecurityContext(ctx context.Context, level SecurityContext, reason string) context.Context {
	ctx = context.WithValue(ctx, contextKeySecurityLevel, level)
	ctx = context.WithValue(ctx, contextKeySecurityReason, reason)
	return ctx
}

// GetSecurityContext returns the security context from ctx, defaulting to UserContext.
func GetSecurityContext(ctx context.Context) SecurityContext {
	if v, ok := ctx.Value(contextKeySecurityLevel).(SecurityContext); ok {
		return v
	}
	return UserContext
}

