/**
 * Ensemble Element - Orchestrates multiple elements working together
 *
 * Ensembles allow combining multiple elements (personas, skills, templates, agents, memories)
 * into cohesive units with controlled activation, conflict resolution, and shared context.
 *
 * ARCHITECTURE:
 * - Extends BaseElement for standard element behavior
 * - Pure business logic (no file operations)
 * - Portfolio-agnostic (PortfolioManager passed to activate())
 *
 * SECURITY MEASURES:
 * 1. Circular dependency detection with DFS algorithm
 * 2. Resource limits (max elements, nesting depth, activation time)
 * 3. Input sanitization for all user-provided data
 * 4. Activation timeout protection
 * 5. Context size limits to prevent memory exhaustion
 * 6. Audit logging for security events
 * 7. Condition validation to prevent code injection
 */
import { BaseElement } from '../BaseElement.js';
import { IElement, ElementValidationResult } from '../../types/elements/index.js';
import { PortfolioManager } from '../../portfolio/PortfolioManager.js';
import { MetadataService } from '../../services/MetadataService.js';
import { EnsembleMetadata, EnsembleElement, EnsembleActivationResult, EnsembleActivationMetrics } from './types.js';
import { ResolvedEnsembleLimits } from './constants.js';
/**
 * Ensemble class - Orchestrates multiple elements as a cohesive unit
 *
 * Extends BaseElement to inherit:
 * - Standard validation
 * - Serialization
 * - Metadata management
 * - ID generation
 * - Status tracking
 */
export declare class Ensemble extends BaseElement implements IElement {
    metadata: EnsembleMetadata;
    private elements;
    private elementInstances;
    private readonly MAX_INSTANCE_CACHE_SIZE;
    private instanceAccessTimes;
    private sharedContext;
    private activationInProgress;
    private lastActivationResult?;
    private activationMetrics;
    private _effectiveLimits;
    /**
     * Get effective limits for this ensemble
     *
     * Resolves limits in priority order:
     * 1. Per-ensemble overrides (from metadata.resourceLimits)
     * 2. Global configuration (setGlobalEnsembleLimits())
     * 3. Environment variables (ENSEMBLE_MAX_*)
     * 4. Default values
     *
     * Results are cached for performance. Call invalidateLimitsCache() to refresh.
     *
     * @returns Resolved limits object
     */
    getEffectiveLimits(): ResolvedEnsembleLimits;
    /**
     * Invalidate cached limits (call when resourceLimits changes)
     */
    invalidateLimitsCache(): void;
    constructor(metadata: Partial<EnsembleMetadata>, elements: EnsembleElement[] | undefined, metadataService: MetadataService);
    /**
     * Find an element by name in the elements array
     * @param name - Element name to search for
     * @returns Element if found, undefined otherwise
     */
    private findElementByName;
    /**
     * Check if an element exists in the array
     * @param name - Element name to check
     * @returns true if element exists, false otherwise
     */
    private hasElement;
    /**
     * Remove an element from the array by name
     * @param name - Element name to remove
     * @returns true if element was removed, false if not found
     */
    private removeElementByName;
    /**
     * Add or update an element in the array
     * @param element - Element to add or update
     * @returns true if element was added, false if updated
     */
    private setElement;
    /**
     * Sync elements array to metadata (single source of truth)
     */
    private syncElementsToMetadata;
    /**
     * Sync the internal elements array from metadata.elements
     *
     * Use this after metadata.elements has been modified externally
     * (e.g., via editElement) to ensure internal state is consistent.
     */
    syncElementsFromMetadata(): void;
    /**
     * Load element references from metadata
     * Called during construction to populate elements array
     */
    private loadElementsFromMetadata;
    /**
     * Add an element to the ensemble
     *
     * @param element - Element configuration to add
     * @throws Error if element would create circular dependency or exceed limits
     */
    addElement(element: EnsembleElement): void;
    /**
     * Update an element's configuration in the ensemble
     *
     * @param elementName - Name of element to update
     * @param updates - Partial element configuration to merge with existing
     * @throws Error if element not found or activation in progress
     */
    updateElement(elementName: string, updates: Partial<EnsembleElement>): void;
    /**
     * Remove an element from the ensemble
     *
     * @param elementName - Name of element to remove
     * @throws Error if element not found or activation in progress
     */
    removeElement(elementName: string): void;
    /**
     * Activate the element (BaseElement interface implementation)
     * For ensembles, this is a no-op. Use activateEnsemble() for full activation.
     */
    activate(): Promise<void>;
    /**
     * Activate the ensemble and all its elements based on strategy
     *
     * @param portfolioManager - Portfolio manager for loading element instances
     * @param managers - Element managers for loading different element types
     * @param nestingDepth - Current nesting depth (0 for top-level, increments for nested)
     * @returns Activation result with success status and element results
     */
    activateEnsemble(portfolioManager: PortfolioManager, managers: import('./types.js').ElementManagers, nestingDepth?: number): Promise<EnsembleActivationResult>;
    /**
     * Helper to create structured log context for ensemble operations
     * @private
     */
    private getLogContext;
    /**
     * Perform the actual activation logic
     * Extracted to separate method for timeout handling
     */
    private performActivation;
    /**
     * Deactivate the ensemble and all its elements
     */
    deactivate(): Promise<void>;
    /**
     * Validate the ensemble configuration
     * Overrides BaseElement.validate() to add ensemble-specific checks
     */
    validate(): ElementValidationResult;
    /**
     * Determine activation order based on strategy
     */
    private getActivationOrder;
    /**
     * Topological sort for dependency-based activation order
     */
    private topologicalSort;
    /**
     * Activate elements sequentially in dependency order
     */
    private activateSequential;
    /**
     * Activate all elements simultaneously
     */
    private activateAll;
    /**
     * Activate elements by priority (highest first)
     */
    private activatePriority;
    /**
     * Activate elements based on conditions
     */
    private activateConditional;
    /**
     * Activate a single element and track results
     */
    private activateSingleElement;
    /**
     * Activate an element via its type manager's activation method.
     * This registers the element in the manager's active set so that
     * get_active_elements correctly reports it.
     *
     * @returns true if activation went through a manager, false if no manager available
     * @see Issue #1769 - Ensemble activation not registering with type managers
     */
    private activateViaManager;
    /**
     * Load an element instance from portfolio
     */
    private loadElementInstance;
    /**
     * Normalize element type to singular form
     */
    private normalizeElementType;
    /**
     * Get the appropriate manager for an element type
     */
    private getManagerForType;
    /**
     * Get list of available manager types
     */
    private getAvailableManagerTypes;
    /**
     * Find an element in the manager using fuzzy name matching
     */
    private findElementInManager;
    /**
     * Check if element name matches target using fuzzy matching
     * Handles exact match, slugified match, and bidirectional slug matching
     *
     * SECURITY: Normalizes Unicode to prevent composed vs decomposed character mismatches.
     * This is defense-in-depth; element names are already validated by ELEMENT_NAME_PATTERN
     * which blocks non-ASCII characters.
     *
     * @param actualName - Name from element manager (filesystem)
     * @param targetName - Name from ensemble configuration (user input)
     * @returns true if names match exactly or after slugification
     */
    private matchesElementName;
    /**
     * Capitalize first letter of a string
     */
    private capitalizeFirst;
    /**
     * Evict the oldest accessed instance from the cache
     * Implements LRU (Least Recently Used) eviction policy
     */
    private evictOldestInstance;
    /**
     * Clear the element instance cache
     * Useful for freeing memory or forcing reload of elements
     */
    clearInstanceCache(): void;
    /**
     * Build a type-safe context for condition evaluation
     *
     * Constructs a ConditionContext object with all values needed to evaluate
     * an element's activation condition. The context is immutable and only
     * exposes safe, read-only data.
     *
     * SECURITY GUARANTEES:
     * - Only exposes documented, safe properties
     * - No access to element instances or methods
     * - All nested objects are readonly (shallow immutability)
     * - Context values remain type-checked as unknown
     * - No exposure of internal ensemble state
     *
     * PERFORMANCE:
     * - Minimal object allocation (reuses maps where possible)
     * - O(1) lookups for element and context data
     * - Lazy computation of resource metrics
     * - No deep cloning (uses readonly type guards)
     *
     * @param element - The element whose condition is being evaluated
     * @param activationStartTime - Timestamp when ensemble activation began
     * @param result - Current activation result (for tracking progress)
     * @returns Context builder result with context object and metadata
     *
     * @example
     * ```typescript
     * const contextResult = this.buildConditionContext(
     *   elementConfig,
     *   startTime,
     *   activationResult
     * );
     *
     * // Use context in evaluation
     * const shouldActivate = evaluateExpression(
     *   element.condition,
     *   contextResult.context
     * );
     * ```
     */
    private buildConditionContext;
    /**
     * Evaluate an activation condition in a secure VM sandbox
     *
     * SECURITY IMPLEMENTATION:
     * This method evaluates user-provided conditions using Node.js VM module with multiple
     * layers of defense:
     *
     * 1. **Sandboxed Execution**: Uses vm.createContext() with frozen objects
     *    - No access to require, process, global, or other Node.js APIs
     *    - All context objects are deeply frozen (immutable)
     *    - No prototype chain access to prevent pollution
     *
     * 2. **Timeout Protection**: 100ms maximum evaluation time
     *    - Prevents infinite loops and ReDoS attacks
     *    - Terminates long-running expressions
     *
     * 3. **Input Validation**: Pre-validated by isValidCondition()
     *    - Dangerous patterns blocked (eval, Function, require, etc.)
     *    - Only safe operators allowed
     *    - Maximum length enforced
     *
     * 4. **Type Safety**: Enforces boolean return values
     *    - Non-boolean results treated as false
     *    - Prevents side effects from non-expression statements
     *
     * 5. **Error Handling**: Fail-secure principle
     *    - Evaluation errors result in non-activation (return false)
     *    - All failures logged to SecurityMonitor
     *    - No error details leaked to user
     *
     * SUPPORTED FEATURES:
     * - Context variable access: context.*, element.*, state.*, resources.*, environment.*
     * - Comparison operators: ==, !=, ===, !==, >, <, >=, <=
     * - Logical operators: &&, ||, !
     * - Parentheses for grouping
     * - Array/object property access
     *
     * Example valid conditions:
     * - "element.priority >= 80"
     * - "context.security_review === true"
     * - "state.activatedCount > 3 && element.role === 'primary'"
     * - "context.environment === 'production' || context.override"
     *
     * @param condition - The condition string to evaluate (pre-validated)
     * @param element - The element whose condition is being evaluated
     * @param activationStartTime - When activation began (for resource tracking)
     * @param result - Current activation result (for state tracking)
     * @returns true if condition evaluates to true, false otherwise
     * @private
     * @security Multiple defense layers: sandbox, timeout, validation, immutability
     */
    private evaluateCondition;
    /**
     * Check if a condition syntax is valid
     *
     * Validates that a condition:
     * 1. Matches the safe character pattern (alphanumeric, operators, etc.)
     * 2. Does not contain dangerous keywords or operators
     * 3. Is not empty or whitespace-only
     *
     * SECURITY: Multi-layer validation approach
     * - Layer 1: Positive pattern match (CONDITION_PATTERN) allows only safe characters
     * - Layer 2: Negative pattern match (DANGEROUS_CONDITION_PATTERNS) blocks code injection
     * - Layer 3: VM sandbox with timeout during evaluation (see evaluateCondition)
     * This defense-in-depth strategy ensures conditions cannot execute arbitrary code
     *
     * @param condition - The condition string to validate
     * @returns true if condition is safe, false otherwise
     */
    private isValidCondition;
    /**
     * Check if adding an element would create a circular dependency
     */
    private wouldCreateCircularDependency;
    /**
     * Find circular dependency path for error reporting
     */
    private findCircularDependency;
    /**
     * Detect all circular dependencies in the ensemble
     */
    private detectAllCircularDependencies;
    /**
     * Set a value in shared context
     *
     * SECURITY: Size limits prevent memory exhaustion attacks
     * - Individual value size capped at MAX_CONTEXT_VALUE_SIZE (10KB)
     * - Total context entries capped at MAX_CONTEXT_SIZE (1000 entries)
     * - Prevents DoS via unbounded context growth
     * These limits allow legitimate use while blocking malicious payloads
     *
     * @param key - Context key (sanitized)
     * @param value - Value to store (size-limited)
     * @param ownerElementName - Element setting this value (validated)
     */
    setContextValue(key: string, value: unknown, ownerElementName: string): void;
    /**
     * Get a value from shared context
     */
    getContextValue(key: string): unknown;
    /**
     * Clear all or specific context values
     *
     * @param ownerElementName - Optional: only clear values owned by this element
     * @throws Error if trying to clear during activation
     */
    clearContext(ownerElementName?: string): void;
    /**
     * Type guard to check if a value is a plain object (not null, not array)
     */
    private isPlainObject;
    /**
     * Resolve a context conflict based on configured strategy
     */
    private resolveConflict;
    /**
     * Update activation metrics after an activation attempt
     * @private
     */
    private updateActivationMetrics;
    /**
     * Get activation metrics for performance monitoring
     * Returns a snapshot of current metrics
     */
    getActivationMetrics(): Readonly<EnsembleActivationMetrics>;
    /**
     * Get the last activation result
     */
    getLastActivationResult(): EnsembleActivationResult | undefined;
    /**
     * Get all elements in the ensemble
     */
    getElements(): EnsembleElement[];
    /**
     * Get a specific element by name
     */
    getElement(name: string): EnsembleElement | undefined;
}
export type { EnsembleMetadata, EnsembleElement } from './types.js';
//# sourceMappingURL=Ensemble.d.ts.map