/**
 * Install AI customization elements from collection with source priority support
 * Supports all element types: personas, skills, templates, agents, memories, ensembles
 *
 * FEATURE (Issue #1447): Added source priority support - checks local → GitHub → collection
 * in priority order during installation to prevent duplicate installations.
 *
 * SECURITY FIX (2025-08-12): Fixed critical vulnerability where content was written to disk
 * BEFORE validation was complete. This could allow malicious content to persist on the
 * filesystem even when validation failed. The fix implements:
 *
 * 1. VALIDATE-BEFORE-WRITE PATTERN: All content validation (ContentValidator.sanitizePersonaContent,
 *    SecureYamlParser.safeMatter, metadata validation, etc.) is now performed BEFORE any disk operations.
 *
 * 2. ATOMIC FILE OPERATIONS: Uses temporary file + atomic rename to prevent partial file corruption
 *    and ensure complete cleanup on any failure during the write process.
 *
 * 3. GUARANTEED CLEANUP: If any part of the write operation fails, temporary files are automatically
 *    cleaned up, preventing orphaned malicious content on the filesystem.
 *
 * The vulnerability existed in installContent() where fs.writeFile() was called after validation
 * but before final success confirmation, creating a window where malicious content could persist.
 */
import { GitHubClient } from './GitHubClient.js';
import { IElementMetadata } from '../types/elements/IElement.js';
import { PortfolioManager, ElementType } from '../portfolio/PortfolioManager.js';
import { ElementSource } from '../config/sourcePriority.js';
import { UnifiedIndexManager } from '../portfolio/UnifiedIndexManager.js';
import { IFileOperationsService } from '../services/FileOperationsService.js';
/**
 * Result of an element installation operation
 */
export interface InstallResult {
    /** Whether the installation succeeded */
    success: boolean;
    /** User-friendly message describing the result */
    message: string;
    /** Element metadata (if installation succeeded) */
    metadata?: IElementMetadata;
    /** Element type */
    elementType?: ElementType;
    /** Filename of the installed element */
    filename?: string;
    /** Source from which the element was installed */
    source?: ElementSource;
    /** Whether the element already existed and was skipped */
    alreadyExists?: boolean;
}
/**
 * Options for element installation
 */
export interface InstallOptions {
    /** Preferred source to install from (overrides priority order) */
    preferredSource?: ElementSource;
    /** Force overwrite even if element exists locally */
    force?: boolean;
    /** Enable fallback to next source if current source fails */
    fallbackOnError?: boolean;
}
export declare class ElementInstaller {
    private githubClient;
    private portfolioManager;
    private baseUrl;
    private readonly sourcePriorityConfig;
    private readonly unifiedIndexManager;
    private readonly fileOperations;
    constructor(githubClient: GitHubClient, options: {
        portfolioManager: PortfolioManager;
        unifiedIndexManager: UnifiedIndexManager;
        fileOperations?: IFileOperationsService;
    });
    /**
     * Install element with source priority support (Issue #1447)
     *
     * Checks sources in priority order (local → GitHub → collection by default):
     * 1. Checks if element already exists locally (prevents duplicate installation)
     * 2. If not local, attempts GitHub portfolio (if specified)
     * 3. Falls back to collection (existing behavior)
     *
     * @param elementName - Name of the element to install
     * @param elementType - Type of element (persona, skill, etc.)
     * @param collectionPath - Path in collection (for collection source)
     * @param options - Installation options
     * @returns InstallResult with success status and details
     *
     * @example
     * // Install from best available source (checks local → GitHub → collection)
     * const result = await installer.installElement('creative-writer', ElementType.PERSONA,
     *   'library/personas/writing/creative-writer.md');
     *
     * @example
     * // Force install from collection even if exists locally
     * const result = await installer.installElement('creative-writer', ElementType.PERSONA,
     *   'library/personas/writing/creative-writer.md', { force: true });
     *
     * @example
     * // Install from specific source
     * const result = await installer.installElement('creative-writer', ElementType.PERSONA,
     *   'library/personas/writing/creative-writer.md',
     *   { preferredSource: ElementSource.COLLECTION });
     *
     * REFACTORED: Reduced cognitive complexity by extracting helper methods
     * ENHANCEMENT (PR #1453): Added input validation for elementName
     * ENHANCEMENT (PR #1453): Added structured logging for debugging
     */
    installElement(elementName: string, elementType: ElementType, collectionPath: string, options?: InstallOptions): Promise<InstallResult>;
    /**
     * Check local element existence if force is not enabled
     * Extracted from installElement() to reduce cognitive complexity
     *
     * @param elementName - Name of element to check
     * @param elementType - Type of element
     * @param force - Whether to skip the check
     * @returns InstallResult if element exists, null otherwise
     * @private
     */
    private checkLocalElementIfNeeded;
    /**
     * Determine source priority order based on preferred source
     * Extracted from installElement() to reduce cognitive complexity
     *
     * @param preferredSource - Optional preferred source to prioritize
     * @returns Array of sources in priority order
     * @private
     */
    private determineSourcePriority;
    /**
     * Try installing from sources in priority order
     * Extracted from installElement() to reduce cognitive complexity
     *
     * @param sourcePriority - Sources to try in order
     * @param elementName - Name of element
     * @param elementType - Type of element
     * @param collectionPath - Collection path
     * @param fallbackOnError - Whether to continue on errors
     * @returns InstallResult
     * @throws Error if all sources fail
     * @private
     */
    private trySourcesInOrder;
    /**
     * Try installing from a single source with error handling
     * Extracted from trySourcesInOrder() to reduce cognitive complexity
     *
     * ENHANCEMENT (PR #1453): Added detailed error context and retry suggestions
     * ENHANCEMENT (PR #1453): Added structured logging for debugging
     *
     * @param source - Source to try
     * @param elementName - Name of element
     * @param elementType - Type of element
     * @param collectionPath - Collection path
     * @param fallbackOnError - Whether to continue on errors
     * @returns Object with success flag and optional error
     * @private
     */
    private tryInstallFromSource;
    /**
     * Format detailed error message with context and retry suggestions
     * ENHANCEMENT (PR #1453): Provides helpful guidance to users when installation fails
     *
     * @param source - Source that failed
     * @param elementName - Name of element
     * @param error - Original error
     * @returns Formatted error message with suggestions
     * @private
     */
    private formatInstallationError;
    /**
     * Create comprehensive error for when all sources fail
     * Extracted to reduce cognitive complexity
     *
     * ENHANCEMENT (PR #1453): Added retry suggestions when all sources fail
     *
     * @param errors - Array of errors from each source
     * @returns Error with formatted summary and suggestions
     * @private
     */
    private createAllSourcesFailedError;
    /**
     * Install element from a specific source
     *
     * @param source - Source to install from
     * @param elementName - Name of element
     * @param elementType - Type of element
     * @param collectionPath - Path in collection (for collection source)
     * @returns InstallResult
     * @private
     */
    private installFromSource;
    /**
     * Check if element exists locally
     *
     * ENHANCEMENT (PR #1453): Added optional chaining for robustness
     *
     * @param elementName - Name of element to check
     * @param elementType - Type of element
     * @returns true if element exists locally
     * @private
     */
    private checkLocalElement;
    /**
     * Install element from GitHub portfolio (Issue #1447)
     *
     * Fetches element from user's GitHub dollhouse-portfolio repository.
     *
     * ENHANCEMENT (PR #1453): Added elementName validation before filename generation
     * ENHANCEMENT (PR #1453): Added optional chaining for robustness
     * ENHANCEMENT (PR #1453): Added structured logging for debugging
     *
     * @param elementName - Name of element to install
     * @param elementType - Type of element
     * @returns InstallResult
     * @private
     */
    private installFromGitHub;
    /**
     * Install element from collection (refactored from installContent)
     *
     * REFACTORED: Reduced cognitive complexity by extracting validation and processing steps
     * ENHANCEMENT (PR #1453): Added structured logging for debugging
     *
     * @param collectionPath - Path in collection
     * @returns InstallResult
     * @private
     */
    private installFromCollection;
    /**
     * Validate collection path and extract element type
     * Extracted from installFromCollection() to reduce cognitive complexity
     *
     * @param sanitizedPath - Sanitized collection path
     * @returns Element type
     * @throws Error if path format is invalid
     * @private
     */
    private validateAndExtractElementType;
    /**
     * Fetch content from collection with size validation
     * Extracted from installFromCollection() to reduce cognitive complexity
     *
     * @param sanitizedPath - Sanitized collection path
     * @returns Decoded content string
     * @throws Error if fetch fails or size exceeds limits
     * @private
     */
    private fetchCollectionContent;
    /**
     * Validate and sanitize collection content
     * Extracted from installFromCollection() to reduce cognitive complexity
     *
     * @param content - Raw content from collection
     * @returns Sanitized content and parsed metadata
     * @throws Error if validation fails
     * @private
     */
    private validateCollectionContent;
    /**
     * Remove prototype-pollution keys from metadata objects.
     */
    private sanitizeMetadata;
    /**
     * Parse YAML content with security error handling
     * Extracted to reduce cognitive complexity
     *
     * @param content - Content to parse
     * @returns Parsed matter result with metadata
     * @throws Error if parsing fails or security threat detected
     * @private
     */
    private parseSecureYaml;
    /**
     * Validate metadata for security threats
     * Extracted to reduce cognitive complexity
     *
     * @param metadata - Metadata to validate
     * @throws Error if validation fails
     * @private
     */
    private validateMetadataSecurity;
    /**
     * Prepare file path for installation
     * Extracted from installFromCollection() to reduce cognitive complexity
     *
     * @param sanitizedPath - Sanitized collection path
     * @param elementType - Element type
     * @returns Filename, local path, and element directory
     * @private
     */
    private prepareFilePath;
    /**
     * Check if file already exists
     * Extracted from installFromCollection() to reduce cognitive complexity
     *
     * @param localPath - Local file path to check
     * @param filename - Filename for error message
     * @returns InstallResult if file exists, null otherwise
     * @private
     */
    private checkFileExists;
    /**
     * Install AI customization element from the collection (backward compatible)
     *
     * DEPRECATED: Use installElement() for source priority support
     *
     * Automatically detects element type from path structure
     *
     * SECURITY FIX: Implements validate-before-write pattern with atomic operations
     * to prevent malicious content persistence on validation failure.
     */
    installContent(inputPath: string): Promise<{
        success: boolean;
        message: string;
        metadata?: IElementMetadata;
        elementType?: ElementType;
        filename?: string;
    }>;
    /**
     * Atomic file write operation with guaranteed cleanup on failure
     *
     * SECURITY FIX: This method ensures that file writes are atomic and any
     * failures during the write process will not leave partial or corrupted
     * files on the filesystem. Uses temporary file + rename for atomicity.
     *
     * @param destination - Final destination path for the file
     * @param content - Content to write to the file
     * @throws Error if write operation fails (with guaranteed cleanup)
     */
    private atomicWriteFile;
    /**
     * Get ElementType from string
     */
    private getElementTypeFromString;
    /**
     * Format installation success message
     */
    formatInstallSuccess(metadata: IElementMetadata, filename: string, elementType: ElementType): string;
}
//# sourceMappingURL=ElementInstaller.d.ts.map