/**
 * Type definitions for element-agnostic query services
 *
 * This module provides reusable interfaces for querying, filtering, sorting,
 * and paginating any element type in the DollhouseMCP system.
 *
 * Design Principles:
 * 1. Element-agnostic: Works with any T that extends IElement
 * 2. Composable: Services can be used independently or combined
 * 3. Consistent: Follows patterns from src/types/collection.ts
 * 4. Secure: All inputs require validation before use
 *
 * @see src/types/collection.ts for collection-specific pagination patterns
 * @see src/types/elements/IElement.ts for base element interface
 */
import { IElement, IElementMetadata } from '../../types/elements/IElement.js';
/**
 * Pagination configuration options
 *
 * Follows collection.ts patterns:
 * - 1-indexed pages (page 1 is first page)
 * - Default pageSize of 20 (Issue #299)
 * - Maximum pageSize enforced by implementations
 *
 * SECURITY: Validate page and pageSize before use to prevent:
 * - Negative page numbers
 * - Zero or negative page sizes
 * - Excessively large page sizes (DoS risk)
 */
export interface PaginationOptions {
    /**
     * Page number (1-indexed)
     * @default 1
     * @minimum 1
     */
    page?: number;
    /**
     * Number of items per page
     * @default 20
     * @minimum 1
     * @maximum Implementation-defined (typically 100)
     */
    pageSize?: number;
}
/**
 * Pagination metadata returned with query results
 *
 * Provides complete pagination state to enable:
 * - UI pagination controls
 * - Next/previous page navigation
 * - Total result set size awareness
 */
export interface PaginationMetadata {
    /**
     * Current page number (1-indexed)
     */
    page: number;
    /**
     * Number of items per page
     */
    pageSize: number;
    /**
     * Total number of items across all pages
     */
    totalItems: number;
    /**
     * Total number of pages
     */
    totalPages: number;
    /**
     * Whether there is a next page available
     */
    hasNextPage: boolean;
    /**
     * Whether there is a previous page available
     */
    hasPrevPage: boolean;
}
/**
 * Generic paginated result container
 *
 * Wraps any array of items with pagination metadata.
 * Used as base type for more specific result types.
 *
 * @template T - Type of items in the result set
 */
export interface PaginatedResult<T> {
    /**
     * Items for the current page
     */
    items: T[];
    /**
     * Pagination metadata
     */
    pagination: PaginationMetadata;
}
/**
 * Filter criteria for querying elements
 *
 * All criteria are optional and combined with AND logic when multiple
 * filters are specified (except tagsAny which uses OR).
 *
 * SECURITY NOTES:
 * 1. All string inputs MUST be sanitized to prevent injection attacks
 * 2. Date inputs MUST be validated to ensure valid ISO 8601 format
 * 3. Tag arrays MUST be validated to prevent array manipulation attacks
 * 4. Status values MUST be validated against ElementStatus enum
 *
 * @example
 * {
 *   nameContains: 'code review',
 *   tags: ['typescript', 'linting'],  // AND logic: has both tags
 *   tagsAny: ['javascript', 'python'], // OR logic: has either tag
 *   author: 'alice',
 *   createdAfter: '2024-01-01T00:00:00Z',
 *   status: 'active'
 * }
 */
export interface FilterCriteria {
    /**
     * Filter by partial name match (case-insensitive)
     * Implementation should use fuzzy matching or contains logic
     *
     * SECURITY: Sanitize input, limit length to prevent ReDoS
     */
    nameContains?: string;
    /**
     * Filter by tags (AND logic - element must have ALL specified tags)
     *
     * SECURITY: Validate each tag string, limit array size
     */
    tags?: string[];
    /**
     * Filter by tags (OR logic - element must have ANY of the specified tags)
     *
     * SECURITY: Validate each tag string, limit array size
     */
    tagsAny?: string[];
    /**
     * Filter by author username
     *
     * SECURITY: Sanitize input, validate against username pattern
     */
    author?: string;
    /**
     * Filter for elements created after this date (inclusive)
     *
     * SECURITY: Validate ISO 8601 format, ensure valid date
     * @format ISO 8601 date-time string
     */
    createdAfter?: string;
    /**
     * Filter for elements created before this date (inclusive)
     *
     * SECURITY: Validate ISO 8601 format, ensure valid date
     * @format ISO 8601 date-time string
     */
    createdBefore?: string;
    /**
     * Filter by element status
     * - 'active': Only active elements
     * - 'inactive': Only inactive elements
     * - 'all': All elements regardless of status (default)
     *
     * SECURITY: Validate against ElementStatus enum values
     */
    status?: 'active' | 'inactive' | 'all';
    /**
     * Filter by partial description match (case-insensitive substring)
     *
     * SECURITY: Sanitize input, limit length to prevent ReDoS
     */
    descriptionContains?: string;
    /**
     * Filter by category (case-insensitive exact match on metadata.category)
     *
     * SECURITY: Sanitize input, limit length
     */
    category?: string;
}
/**
 * Applied filter summary for query results
 *
 * Reports which filters were actually applied to help users
 * understand the result set.
 */
export interface AppliedFilters {
    /**
     * Name filter that was applied
     */
    nameContains?: string;
    /**
     * Tags that were required (AND logic)
     */
    tags?: string[];
    /**
     * Tags where any match was required (OR logic)
     */
    tagsAny?: string[];
    /**
     * Author filter that was applied
     */
    author?: string;
    /**
     * Created after date filter
     */
    createdAfter?: string;
    /**
     * Created before date filter
     */
    createdBefore?: string;
    /**
     * Status filter that was applied
     */
    status?: 'active' | 'inactive' | 'all';
    /**
     * Description filter that was applied
     */
    descriptionContains?: string;
    /**
     * Category filter that was applied
     */
    category?: string;
    /**
     * Total number of filters applied
     */
    count: number;
}
/**
 * Sort order direction
 */
export type SortOrder = 'asc' | 'desc';
/**
 * Fields available for sorting
 *
 * Standard fields available on all elements:
 * - name: Element name (from metadata)
 * - created: Creation timestamp (from metadata)
 * - modified: Last modification timestamp (from metadata)
 * - version: Semantic version (from metadata)
 *
 * Element-specific fields:
 * - retention: Memory-specific retention policy field
 *
 * Implementations should handle missing fields gracefully
 * (e.g., sort nulls last).
 */
export type SortableField = 'name' | 'created' | 'modified' | 'version' | 'retention';
/**
 * Sorting configuration options
 *
 * SECURITY: Validate sortBy against SortableField enum to prevent
 * arbitrary field access or injection attacks.
 */
export interface SortOptions {
    /**
     * Field to sort by
     * @default 'name'
     */
    sortBy?: SortableField;
    /**
     * Sort order direction
     * @default 'asc'
     */
    sortOrder?: SortOrder;
}
/**
 * Applied sorting metadata for query results
 *
 * Reports the actual sorting that was applied to the result set.
 */
export interface AppliedSorting {
    /**
     * Field that was used for sorting
     */
    sortBy: SortableField;
    /**
     * Sort order that was applied
     */
    sortOrder: SortOrder;
}
/**
 * Aggregation options for count/group_by queries (Issue #309).
 * When present, the query returns aggregation results instead of paginated items.
 */
export interface AggregationOptions {
    /**
     * If true, return only the count of matching elements (no items).
     */
    count?: boolean;
    /**
     * Group results by a metadata field (e.g., 'category', 'author', 'tags').
     * Returns a Record<string, number> mapping field values to counts.
     */
    group_by?: string;
}
/**
 * Complete query options combining pagination, filtering, and sorting
 *
 * All options are optional. Defaults:
 * - Pagination: page=1, pageSize=20
 * - Filters: none applied
 * - Sort: sortBy='name', sortOrder='asc'
 * - Aggregate: none (returns items). When set, returns count/groups instead.
 *
 * @example
 * ```typescript
 * // Paginated listing
 * { pagination: { page: 2, pageSize: 10 }, filters: { tags: ['typescript'] }, sort: { sortBy: 'modified', sortOrder: 'desc' } }
 *
 * // Count aggregation
 * { aggregate: { count: true } }
 *
 * // Grouped count
 * { aggregate: { count: true, group_by: 'category' }, filters: { status: 'active' } }
 * ```
 */
export interface QueryOptions {
    /**
     * Pagination configuration
     */
    pagination?: PaginationOptions;
    /**
     * Filter criteria
     */
    filters?: FilterCriteria;
    /**
     * Sorting configuration
     */
    sort?: SortOptions;
    /**
     * Aggregation options (Issue #309).
     * When present, returns count/group_by results instead of paginated items.
     */
    aggregate?: AggregationOptions;
}
/**
 * Complete query result with items, pagination, sorting, and filter metadata
 *
 * Extends PaginatedResult with additional context about the query
 * that was executed.
 *
 * @template T - Type of items in the result set (must extend IElement)
 */
export interface QueryResult<T extends IElement> extends PaginatedResult<T> {
    /**
     * Sorting that was applied
     */
    sorting: AppliedSorting;
    /**
     * Filters that were applied
     */
    filters: {
        /**
         * Summary of applied filters
         */
        applied: AppliedFilters;
    };
}
/**
 * Service interface for pagination operations
 *
 * Provides utilities to paginate any array of items with consistent
 * behavior across the application.
 *
 * Implementation requirements:
 * - Validate pagination options
 * - Handle empty arrays gracefully
 * - Return accurate metadata
 * - Use 1-indexed pages
 *
 * @template T - Type of items being paginated
 */
export interface IPaginationService<T> {
    /**
     * Paginate an array of items
     *
     * @param items - Complete array of items to paginate
     * @param options - Pagination configuration
     * @returns Paginated result with metadata
     * @throws {Error} If pagination options are invalid
     */
    paginate(items: T[], options?: PaginationOptions): PaginatedResult<T>;
    /**
     * Calculate pagination metadata without returning items
     *
     * Useful for API responses where you need metadata but already
     * have the items.
     *
     * @param totalItems - Total number of items in full result set
     * @param options - Pagination configuration
     * @returns Pagination metadata only
     */
    calculateMetadata(totalItems: number, options?: PaginationOptions): PaginationMetadata;
}
/**
 * Service interface for filtering operations
 *
 * Provides utilities to filter arrays of elements based on metadata
 * and other criteria.
 *
 * Implementation requirements:
 * - Sanitize all filter inputs
 * - Support partial matches for name
 * - Handle missing metadata fields gracefully
 * - Combine multiple filters with AND logic (except tagsAny)
 * - Return empty array if no items match
 *
 * @template T - Type of items being filtered (must extend IElement)
 */
export interface IFilterService<T extends IElement> {
    /**
     * Filter an array of elements based on criteria
     *
     * @param items - Array of elements to filter
     * @param criteria - Filter criteria to apply
     * @returns Filtered array (may be empty)
     * @throws {Error} If filter criteria contain invalid values
     */
    filter(items: T[], criteria?: FilterCriteria): T[];
    /**
     * Build a summary of which filters will be applied
     *
     * Useful for logging and debugging query execution.
     *
     * @param criteria - Filter criteria
     * @returns Summary of applicable filters
     */
    summarizeFilters(criteria?: FilterCriteria): AppliedFilters;
    /**
     * Validate filter criteria without applying them
     *
     * @param criteria - Filter criteria to validate
     * @returns True if criteria are valid
     * @throws {Error} If criteria are invalid
     */
    validateCriteria(criteria?: FilterCriteria): boolean;
}
/**
 * Service interface for sorting operations
 *
 * Provides utilities to sort arrays of elements by various fields.
 *
 * Implementation requirements:
 * - Validate sort options
 * - Handle missing field values (sort nulls last)
 * - Support case-insensitive string sorting
 * - Support semantic version sorting
 * - Support ISO 8601 date sorting
 * - Maintain stable sort order
 *
 * @template T - Type of items being sorted (must extend IElement)
 */
export interface ISortService<T extends IElement> {
    /**
     * Sort an array of elements
     *
     * @param items - Array of elements to sort
     * @param options - Sorting configuration
     * @returns Sorted array (does not mutate original)
     * @throws {Error} If sort options are invalid
     */
    sort(items: T[], options?: SortOptions): T[];
    /**
     * Get the default sorting configuration
     *
     * @returns Default sort options
     */
    getDefaultSorting(): AppliedSorting;
    /**
     * Validate sort options without applying them
     *
     * @param options - Sort options to validate
     * @returns True if options are valid
     * @throws {Error} If options are invalid
     */
    validateOptions(options?: SortOptions): boolean;
}
/**
 * Combined service interface for element querying
 *
 * Orchestrates pagination, filtering, and sorting into a single
 * cohesive query operation.
 *
 * Implementation requirements:
 * - Validate all query options
 * - Apply operations in correct order: filter → sort → paginate
 * - Return complete query result with metadata
 * - Log query execution for debugging
 * - Handle empty result sets gracefully
 *
 * CONCURRENT MODIFICATION BEHAVIOR:
 * Query services operate on a snapshot of elements passed to them.
 * They are stateless and do not track file system changes. If elements
 * are modified on disk between fetch and query, results may be inconsistent
 * with the current file system state. For real-time consistency, callers
 * should re-fetch elements before each query.
 *
 * @template T - Type of elements being queried (must extend IElement)
 */
export interface IElementQueryService<T extends IElement> {
    /**
     * Execute a complete query operation
     *
     * Order of operations:
     * 1. Filter items based on criteria
     * 2. Sort filtered items
     * 3. Paginate sorted items
     *
     * SNAPSHOT SEMANTICS:
     * This method operates on the array of elements passed to it at the time
     * of the call. It does not track file system changes or re-read elements.
     * If elements are modified between fetch and query, results reflect the
     * state at fetch time, not query time. This is expected behavior for a
     * stateless service.
     *
     * @param items - Array of elements to query (snapshot at time of call)
     * @param options - Complete query configuration
     * @returns Query result with items and metadata
     * @throws {Error} If query options are invalid
     */
    query(items: T[], options?: QueryOptions): QueryResult<T>;
    /**
     * Execute query and return only the items (no metadata)
     *
     * Convenience method for cases where you only need the items.
     *
     * @param items - Array of elements to query
     * @param options - Complete query configuration
     * @returns Array of items matching query
     */
    queryItems(items: T[], options?: QueryOptions): T[];
    /**
     * Get the default query options
     *
     * @returns Default query configuration
     */
    getDefaultOptions(): Required<QueryOptions>;
    /**
     * Validate query options without executing query
     *
     * @param options - Query options to validate
     * @returns True if options are valid
     * @throws {Error} If options are invalid
     */
    validateOptions(options?: QueryOptions): boolean;
}
/**
 * Type guard to check if an element has required metadata for filtering
 *
 * @param element - Element to check
 * @returns True if element has valid metadata
 */
export declare function hasFilterableMetadata(element: unknown): element is {
    metadata: IElementMetadata;
};
/**
 * Type guard to check if metadata has a specific field
 *
 * @param metadata - Metadata object
 * @param field - Field name to check
 * @returns True if field exists and is not undefined
 */
export declare function hasMetadataField<K extends keyof IElementMetadata>(metadata: IElementMetadata, field: K): metadata is IElementMetadata & Required<Pick<IElementMetadata, K>>;
/**
 * Safely extract an arbitrary metadata field value from an element.
 *
 * Replaces the unsafe double cast pattern:
 *   `el.metadata as unknown as Record<string, unknown>`
 *
 * Handles both known IElementMetadata fields and arbitrary metadata
 * properties that element types may add (e.g., category on skills).
 *
 * @param element - Element to read from
 * @param field - Metadata field name to extract
 * @returns The field value, or undefined if the element lacks metadata or the field
 *
 * @example
 * ```typescript
 * const category = getMetadataField(element, 'category'); // unknown
 * const tags = getMetadataField(element, 'tags');         // unknown
 * ```
 */
export declare function getMetadataField(element: IElement, field: string): unknown;
/**
 * Extract sortable value from element for a given field
 *
 * Safely extracts the value used for sorting, handling missing fields
 * and element-specific fields (like retention for memories).
 *
 * @param element - Element to extract value from
 * @param field - Field to extract
 * @returns Value to use for sorting, or undefined if not available
 */
export declare function extractSortValue(element: IElement, field: SortableField): string | number | undefined;
//# sourceMappingURL=types.d.ts.map