/**
 * Repository Pattern Types
 *
 * This module defines the interfaces for the Repository pattern,
 * enabling access to created resources with Identity Map caching
 * and Specification-based queries.
 *
 * The Repository pattern provides:
 * - Centralized resource access
 * - Identity Map for caching and preventing duplicates
 * - Specification-based queries
 * - Type-safe resource retrieval
 *
 * @module declarative-api/repository.types
 */
import type { ResourceType } from './core.types';
import type { IResourceEntity } from './resource.types';
import type { ISpecification } from './specification.types';
/**
 * Repository interface for accessing created resources with Identity Map.
 *
 * Implements the Repository pattern with support for:
 * - Basic CRUD operations (getById, getByType, getAll)
 * - Specification-based queries
 * - Identity Map caching
 * - Cross-stack resource imports
 *
 * @example
 * ```typescript
 * // Get resource by ID
 * const table = repository.getById<ITableResourceEntity>('users-table');
 *
 * // Get all resources of a type
 * const queues = repository.getByType<IQueueResourceEntity>('sqs:queue');
 *
 * // Query with specification
 * const prodResources = repository.query(new StageSpecificSpec('prod'));
 *
 * // Check existence
 * if (repository.exists('users-table')) {
 *   // Resource exists
 * }
 * ```
 *
 * Validates: Requirements 10.1, 10.2, 10.3, 10.4, 10.5, 10.6
 */
export interface IResourceRepository {
    /**
     * Get a resource by its unique identifier.
     *
     * @typeParam T - The expected resource entity type
     * @param id - The unique resource identifier
     * @returns The resource entity
     * @throws ResourceNotFoundException if resource does not exist
     */
    getById<T extends IResourceEntity>(id: string): T;
    /**
     * Get a resource by its unique identifier, or null if not found.
     *
     * @typeParam T - The expected resource entity type
     * @param id - The unique resource identifier
     * @returns The resource entity or null
     */
    getByIdOrNull<T extends IResourceEntity>(id: string): T | null;
    /**
     * Get all resources of a specific type.
     *
     * @typeParam T - The expected resource entity type
     * @param type - The resource type to filter by
     * @returns Array of matching resource entities
     */
    getByType<T extends IResourceEntity>(type: ResourceType): T[];
    /**
     * Get all registered resources.
     *
     * @returns Array of all resource entities
     */
    getAll(): IResourceEntity[];
    /**
     * Query resources using a specification.
     *
     * @typeParam T - The expected resource entity type
     * @param specification - The specification to filter by
     * @returns Array of matching resource entities
     */
    query<T extends IResourceEntity>(specification: ISpecification<T>): T[];
    /**
     * Check if a resource exists by ID.
     *
     * @param id - The unique resource identifier
     * @returns True if the resource exists
     */
    exists(id: string): boolean;
    /**
     * Register a resource in the repository.
     *
     * This is typically called internally when resources are created.
     * The Identity Map ensures the same resource is not registered twice.
     *
     * @param resource - The resource entity to register
     * @throws DuplicateResourceError if resource with same ID already exists
     */
    register(resource: IResourceEntity): void;
    /**
     * Unregister a resource from the repository.
     *
     * This is typically called internally when resources are deleted.
     *
     * @param id - The unique resource identifier to unregister
     * @returns True if the resource was unregistered, false if not found
     */
    unregister(id: string): boolean;
    /**
     * Get the count of registered resources.
     *
     * @returns The number of registered resources
     */
    count(): number;
    /**
     * Clear all resources from the repository.
     *
     * Use with caution - this removes all cached resources.
     */
    clear(): void;
}
/**
 * Typed repository interface for specific resource types.
 *
 * Provides a type-safe interface for working with a specific
 * resource type, eliminating the need for type parameters on each call.
 *
 * @typeParam T - The resource entity type this repository manages
 *
 * @example
 * ```typescript
 * const tableRepo: ITypedResourceRepository<ITableResourceEntity> =
 *   repositoryFactory.getRepository('dynamodb:table');
 *
 * // All methods return the correct type
 * const table = tableRepo.getById('users-table');
 * const allTables = tableRepo.getAll();
 * ```
 *
 * Validates: Requirements 10.4
 */
export interface ITypedResourceRepository<T extends IResourceEntity> {
    /**
     * Get a resource by its unique identifier.
     *
     * @param id - The unique resource identifier
     * @returns The resource entity
     * @throws ResourceNotFoundException if resource does not exist
     */
    getById(id: string): T;
    /**
     * Get a resource by its unique identifier, or null if not found.
     *
     * @param id - The unique resource identifier
     * @returns The resource entity or null
     */
    getByIdOrNull(id: string): T | null;
    /**
     * Get all resources of this type.
     *
     * @returns Array of all resource entities of this type
     */
    getAll(): T[];
    /**
     * Query resources using a specification.
     *
     * @param specification - The specification to filter by
     * @returns Array of matching resource entities
     */
    query(specification: ISpecification<T>): T[];
    /**
     * Check if a resource exists by ID.
     *
     * @param id - The unique resource identifier
     * @returns True if the resource exists
     */
    exists(id: string): boolean;
    /**
     * Get the count of resources of this type.
     *
     * @returns The number of resources of this type
     */
    count(): number;
}
/**
 * Factory interface for creating typed repositories.
 *
 * @example
 * ```typescript
 * const factory: IResourceRepositoryFactory = new ResourceRepositoryFactory(repository);
 * const tableRepo = factory.getRepository<ITableResourceEntity>('dynamodb:table');
 * ```
 */
export interface IResourceRepositoryFactory {
    /**
     * Get a typed repository for a specific resource type.
     *
     * @typeParam T - The resource entity type
     * @param type - The resource type
     * @returns A typed repository for the specified type
     */
    getRepository<T extends IResourceEntity>(type: ResourceType): ITypedResourceRepository<T>;
}
