import { KosData } from '../util/observable-proxy-map';
import { IKosContainerIndex, IndexMapper } from './kos-container-index';
import { IKosDataModel } from './kosModel';
import { IKosIdentifiable } from './types/model';
export interface IKosBaseContainer<T extends IKosIdentifiable> {
    revision: number;
    data: T[];
    idx: KosData<Record<string, Record<string, T[]>>>;
    index: Map<string, IKosContainerIndex<T>>;
    indexKeys: Record<string, string[] | undefined>;
    addModel: (model: T) => void;
    removeModel: (id: string) => void;
    addAll: (models: T[]) => void;
    removeAll: (ids: string[]) => void;
    getModel: (id: string) => T | undefined;
    increment: () => void;
    clear: () => Promise<void>;
    map: (typeof Array.prototype)["map"];
    filter: (typeof Array.prototype)["filter"];
    sort: (typeof Array.prototype)["sort"];
    [Symbol.iterator](): IterableIterator<T>;
}
export interface IKosModelContainer<T extends IKosDataModel> extends IKosBaseContainer<T> {
    updateModel: (model: T) => void;
    getModel: (id: string) => T | undefined;
    getIndexByKey: (indexName: string, indexKey: string) => T[];
    getIndexKeys: (indexName: string) => string[];
    removeAndDestroy: (id: string) => Promise<void>;
    removeAndDestroyAll: (ids: string[]) => Promise<void>;
    toJSON?: () => object;
}
/**
 * Eviction strategy for container capacity management
 *
 * - **fifo**: First-In-First-Out - removes oldest models first (default for event streams)
 * - **lru**: Least Recently Used - removes models not accessed recently (good for caches)
 * - **custom**: Uses customEvictionFilter function to determine which models to evict
 *
 * @category Container Capacity Management
 * @see {@link ContainerOptions.maxCapacity}
 * @see {@link ContainerOptions.evictionStrategy}
 */
export type EvictionStrategy = "fifo" | "lru" | "custom";
interface ContainerOptions<T extends IKosDataModel> {
    sortKey?: keyof T;
    indexMap?: Record<string, keyof T | IndexMapper<T>>;
    parentId?: string;
    extensionId?: string;
    /**
     * SAFETY NET: Maximum number of models this container can hold.
     * When exceeded, models are automatically evicted and destroyed based on evictionStrategy.
     *
     * **Primary use case**: Prevent memory overflow when cleanup handlers are missing or
     * data becomes inconsistent. Set higher than normal usage to catch edge cases.
     *
     * **Eviction is logged**: All automatic evictions are logged at WARNING level
     * to aid in debugging and identifying data inconsistencies.
     *
     * @category Capacity Management
     * @see {@link EvictionStrategy}
     * @see {@link evictionBatchSize}
     *
     * @example
     * ```typescript
     * containerOptions: {
     *   maxCapacity: 10000,  // Safety net: expect ~100-1000 normally
     *   evictionStrategy: 'fifo'
     * }
     * ```
     */
    maxCapacity?: number;
    /**
     * Strategy for selecting which models to evict when maxCapacity is exceeded.
     *
     * - **fifo** (default): Remove oldest models first - best for event streams, logs
     * - **lru**: Remove least recently accessed models - best for caches
     * - **custom**: Use customEvictionFilter to determine eviction candidates
     *
     * @category Capacity Management
     * @see {@link EvictionStrategy}
     * @see {@link maxCapacity}
     * @see {@link customEvictionFilter}
     *
     * @default 'fifo'
     */
    evictionStrategy?: EvictionStrategy;
    /**
     * Number of models to evict when maxCapacity is exceeded.
     * Removing in batches prevents thrashing at the capacity boundary.
     *
     * @category Capacity Management
     * @see {@link maxCapacity}
     *
     * @default Math.max(10, Math.ceil(maxCapacity * 0.1))
     */
    evictionBatchSize?: number;
    /**
     * Custom filter function for 'custom' eviction strategy.
     * Should return models that are candidates for eviction.
     * The container will evict up to evictionBatchSize models from the returned array.
     *
     * @category Capacity Management
     * @see {@link EvictionStrategy}
     * @see {@link maxCapacity}
     *
     * @example
     * ```typescript
     * // Evict resolved troubles older than 1 hour
     * customEvictionFilter: (models) => {
     *   return models.filter(m =>
     *     m.status === 'resolved' &&
     *     Date.now() - m.resolvedAt > 3600000
     *   );
     * }
     * ```
     */
    customEvictionFilter?: (models: T[]) => T[];
}
export declare class KosModelContainer<T extends IKosDataModel> implements IKosModelContainer<T> {
    _data: Map<string, T>;
    private _sortKey?;
    private _revision;
    private _index;
    private _optionsMap;
    private _disposerMap;
    private _parentId?;
    idx: KosData<Record<string, Record<string, T[]>>>;
    private _maxCapacity?;
    private _evictionStrategy;
    private _evictionBatchSize;
    private _insertionOrder;
    private _accessTimes?;
    private _customEvictionFilter?;
    constructor(options?: ContainerOptions<T>);
    init(): void;
    [Symbol.iterator](): ArrayIterator<T>;
    get index(): Map<string, IKosContainerIndex<T>>;
    get revision(): number;
    get indexKeys(): Record<string, string[] | undefined>;
    sortFn(a: any, b: any): number;
    get data(): T[];
    increment(): void;
    addAll(models: T[]): void;
    removeAll(ids: string[]): void;
    /**
     * Remove a model from the container and destroy it.
     * This is a convenience method that combines removeModel() and destroyKosModel().
     *
     * Use this when:
     * - The model is being permanently removed from the system
     * - The model should be cleaned up and disposed
     *
     * Use removeModel() alone when:
     * - Moving models between containers
     * - Temporarily removing without destroying
     * - Managing models that may be re-added later
     *
     * @param id - The unique identifier of the model to remove and destroy
     */
    removeAndDestroy(id: string): Promise<void>;
    /**
     * Remove multiple models from the container and destroy them.
     * This is a convenience method that combines removeAll() and destroyKosModel().
     *
     * Operations are performed in parallel for efficiency, but each destruction
     * is independent - failures in one won't prevent others from being destroyed.
     *
     * @param ids - Array of unique identifiers of the models to remove and destroy
     * @returns Promise that resolves when all models have been removed and destroyed
     */
    removeAndDestroyAll(ids: string[]): Promise<void>;
    /**
     * Add a model to the container (Zone 2: Workflow orchestration)
     *
     * @param model - The model to add
     * @param defer - If true, skip incrementing revision (for batch operations)
     */
    addModel(model: T, defer?: boolean): void;
    /**
     * Persist model to container storage (Zone 3)
     * @private
     */
    private _persistModel;
    /**
     * Track model metadata for capacity management (Zone 3)
     * @private
     */
    private _trackModelMetadata;
    /**
     * Establish parent-child relationships (Zone 3)
     * @private
     */
    private _establishModelRelationships;
    /**
     * Enforce capacity limits and trigger eviction if needed (Zone 3)
     * @private
     */
    private _enforceCapacityLimits;
    /**
     * Configure MobX observers for model property changes (Zone 3)
     * @private
     */
    private _configureModelMonitoring;
    /**
     * Publish KosContainerIndexEvents.ADDED for an indexable item.
     * No-op when the model carries no INDEX_RECORD_SYMBOL (not opted
     * into indexing) or when the record has no resolvable collection
     * (item has no own tag and no inheritable container context).
     *
     * @private
     */
    private _publishIndexAdded;
    /**
     * Publish KosContainerIndexEvents.REMOVED for an indexable item.
     * Called with the model BEFORE it's deleted from the container so
     * the payload can carry modelType + collection.
     *
     * @private
     */
    private _publishIndexRemoved;
    removeModel(id: string, defer?: boolean): void;
    updateModel(model: T): void;
    getModel(id: string): T | undefined;
    getIndexKeys(indexName: string): string[];
    getIndexByKey(indexName: string, indexKey: string): T[];
    /**
     * SAFETY NET: Evict models when capacity is exceeded (Zone 2: Workflow orchestration)
     * Logs all evictions at WARNING level for debugging.
     * @private
     */
    private _evictModels;
    /**
     * Log capacity exceeded info (Zone 3)
     * @private
     */
    private _logCapacityWarning;
    /**
     * Select models for eviction based on strategy (Zone 3)
     * @private
     */
    private _selectModelsForEviction;
    /**
     * Select oldest models for FIFO eviction (Zone 3)
     * @private
     */
    private _selectFifoModels;
    /**
     * Select least recently used models for LRU eviction (Zone 3)
     * @private
     */
    private _selectLruModels;
    /**
     * Select models using custom filter for eviction (Zone 3)
     * @private
     */
    private _selectCustomModels;
    /**
     * Remove and destroy evicted models (Zone 3)
     * @private
     */
    private _removeEvictedModels;
    /**
     * Log eviction completion (Zone 3)
     * @private
     */
    private _logEvictionComplete;
    clear(): Promise<void>;
    filter<S extends any>(predicate: (value: any, index: number, array: any[]) => value is S, thisArg?: any): T[];
    sort(compareFn?: ((a: any, b: any) => number) | undefined): T[];
    map<U>(callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any): U[];
    forEach(callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any): void;
    toJSON(): {
        indexes: Record<string, string[] | undefined>;
        data: {
            id: string;
            type: string;
        }[];
    };
}
export {};
//# sourceMappingURL=kos-container-model.d.ts.map