<?php

declare(strict_types=1);

namespace App\Framework\Discovery;

use App\Framework\Cache\Cache;
use App\Framework\Context\ExecutionContext;
use App\Framework\Core\Events\EventDispatcher;
use App\Framework\Core\PathProvider;
use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\DateTime\Clock;
use App\Framework\Discovery\Events\CacheHitEvent;
use App\Framework\Discovery\Events\DiscoveryCompletedEvent;
use App\Framework\Discovery\Events\DiscoveryFailedEvent;
use App\Framework\Discovery\Events\DiscoveryStartedEvent;
use App\Framework\Discovery\Memory\DiscoveryMemoryManager;
use App\Framework\Discovery\Memory\MemoryGuard;
use App\Framework\Discovery\Processing\AdaptiveChunker;
use App\Framework\Discovery\Processing\ClassExtractor;
use App\Framework\Discovery\Processing\FileStreamProcessor;
use App\Framework\Discovery\Processing\ProcessingContext;
use App\Framework\Discovery\Processing\VisitorCoordinator;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Discovery\Storage\DiscoveryCacheManager;
use App\Framework\Discovery\ValueObjects\DiscoveryConfiguration;
use App\Framework\Discovery\ValueObjects\DiscoveryContext;
use App\Framework\Discovery\ValueObjects\DiscoveryOptions;
use App\Framework\Discovery\ValueObjects\FileContext;
use App\Framework\Discovery\ValueObjects\MemoryStrategy;
use App\Framework\Discovery\ValueObjects\ScanType;
use App\Framework\Filesystem\ValueObjects\FilePath;
use App\Framework\Filesystem\FileScanner;
use App\Framework\Filesystem\FileSystemService;
use App\Framework\Filesystem\ValueObjects\FilePattern;
use App\Framework\Filesystem\ValueObjects\ScannerMemoryUsage;
use App\Framework\Filesystem\ValueObjects\ScannerMetrics;
use App\Framework\Logging\Logger;
use App\Framework\Logging\ValueObjects\LogContext;
use App\Framework\Performance\EnhancedPerformanceCollector;
use App\Framework\Performance\MemoryMonitor;
use App\Framework\Performance\PerformanceCategory;
use App\Framework\Reflection\ReflectionProvider;
use Throwable;

/**
 * Refactored unified discovery service with clean architecture
 *
 * Key improvements:
 * - Separated concerns into focused components
 * - Shared reflection context to avoid duplication
 * - Stream-based processing for memory efficiency
 * - Plugin-based architecture for extensibility
 */
final readonly class UnifiedDiscoveryService
{
    private ProcessingContext $processingContext;

    private FileStreamProcessor $fileProcessor;

    private FileScanner $fileScanner;

    private VisitorCoordinator $visitorCoordinator;

    private DiscoveryCacheManager $cacheManager;

    private DiscoveryMemoryManager $memoryManager;

    private MemoryGuard $memoryGuard;

    private AdaptiveChunker $adaptiveChunker;

    public function __construct(
        private PathProvider $pathProvider,
        private Cache $cache,
        private Clock $clock,
        private ReflectionProvider $reflectionProvider,
        private DiscoveryConfiguration $configuration,
        /** @var array<class-string, string> $attributeMappers */
        private array $attributeMappers = [],
        /** @var array<int, class-string> $targetInterfaces */
        private array $targetInterfaces = [],
        private ?Logger $logger = null,
        private ?EventDispatcher $eventDispatcher = null,
        private ?MemoryMonitor $memoryMonitor = null,
        private ?FileSystemService $fileSystemService = null,
        private ?EnhancedPerformanceCollector $performanceCollector = null,
        private ?ExecutionContext $executionContext = null
    ) {
        // Validate configuration
        $this->configuration->validate();

        // Use provided FileSystemService or create default
        $fileSystemService = $fileSystemService ?? new FileSystemService();

        // Initialize processing components with configuration-aware setup
        $this->initializeComponents($fileSystemService);
    }

    /**
     * Initialize all processing components
     */
    private function initializeComponents(FileSystemService $fileSystemService): void
    {
        // Initialize processing context with reflection provider
        $this->processingContext = new ProcessingContext($this->reflectionProvider);

        // Initialize memory management system
        $this->initializeMemoryManagement();

        // Create supporting components
        $classExtractor = new ClassExtractor($fileSystemService);

        // FileScanner with conditional monitoring based on configuration
        $this->fileScanner = new FileScanner(
            $this->logger,
            $this->configuration->enableMemoryMonitoring ? $this->memoryMonitor : null,
            $fileSystemService
        );

        // FileStreamProcessor with configuration-aware logging
        $this->fileProcessor = new FileStreamProcessor(
            $this->fileScanner,
            $classExtractor,
            $this->processingContext,
            $this->configuration->enablePerformanceTracking ? $this->logger : null
        );

        // VisitorCoordinator with attribute mappers and interfaces
        $this->visitorCoordinator = new VisitorCoordinator(
            $this->processingContext,
            $this->attributeMappers,
            $this->targetInterfaces,
            $this->logger
        );

        // CacheManager with configuration-based timeout
        $cacheTimeoutHours = (int) ($this->configuration->cacheTimeout->toSeconds() / 3600);
        $this->cacheManager = new DiscoveryCacheManager(
            $this->cache,
            $this->clock,
            $fileSystemService,
            $this->logger,
            $cacheTimeoutHours,
            $this->memoryManager,
            $this->eventDispatcher
        );

        // Initialize adaptive chunker with memory management
        $this->adaptiveChunker = new AdaptiveChunker(
            $this->memoryManager,
            $this->memoryGuard,
            $this->logger,
            $this->eventDispatcher,
            $this->clock
        );
    }

    /**
     * Initialize memory management system
     */
    private function initializeMemoryManagement(): void
    {
        // Create memory limit from configuration
        $memoryLimit = Byte::fromMegabytes($this->configuration->memoryLimitMB);

        // Suggest strategy based on configuration
        $strategy = MemoryStrategy::suggestForDiscovery(
            $this->configuration->maxFilesPerBatch * 10, // Estimate based on batch size
            $this->configuration->memoryLimitMB,
            $this->configuration->enablePerformanceTracking
        );

        // Create memory manager
        $this->memoryManager = new DiscoveryMemoryManager(
            strategy: $strategy,
            memoryLimit: $memoryLimit,
            memoryPressureThreshold: $this->configuration->memoryPressureThreshold,
            memoryMonitor: $this->memoryMonitor,
            logger: $this->logger,
            eventDispatcher: $this->eventDispatcher,
            clock: $this->clock
        );

        // Create memory guard with emergency callback
        $this->memoryGuard = $this->memoryManager->createMemoryGuard(
            emergencyCallback: function () {
                $this->logger?->critical('Emergency memory cleanup triggered during discovery', LogContext::withData([
                    'memory_status' => $this->memoryManager->getMemoryStatus()->toArray(),
                ]));

                // Force cleanup of processing context caches
                $this->processingContext?->clearCaches();

                // Force garbage collection
                gc_collect_cycles();
            }
        );

        $this->logger?->info('Memory management initialized', LogContext::withData([
            'strategy' => $strategy->value,
            'memory_limit' => $memoryLimit->toHumanReadable(),
            'pressure_threshold' => $this->configuration->memoryPressureThreshold,
        ]));
    }

    /**
     * Modern unified discovery with enhanced features
     */
    public function discover(): DiscoveryRegistry
    {
        // Use configuration paths if provided, otherwise default to src
        $paths = ! empty($this->configuration->paths)
            ? $this->configuration->paths
            : [$this->pathProvider->getBasePath() . '/src'];

        $options = new DiscoveryOptions(
            scanType: ScanType::FULL,
            paths: $paths,
            useCache: $this->configuration->useCache
        );

        return $this->discoverWithOptions($options);
    }

    /**
     * Incremental discovery for changed directories
     */
    public function incrementalDiscover(): DiscoveryRegistry
    {
        // Use configuration paths if provided, otherwise default to src
        $paths = ! empty($this->configuration->paths)
            ? $this->configuration->paths
            : [$this->pathProvider->getBasePath() . '/src'];

        $options = new DiscoveryOptions(
            scanType: ScanType::INCREMENTAL,
            paths: $paths,
            useCache: false // Incremental discovery doesn't use cache
        );

        return $this->discoverWithOptions($options);
    }

    /**
     * Discovery with custom options
     */
    public function discoverWithOptions(DiscoveryOptions $options): DiscoveryRegistry
    {
        $context = new DiscoveryContext(
            paths: $options->paths,
            scanType: $options->scanType,
            options: $options,
            startTime: $this->clock->now(),
            executionContext: $this->executionContext
        );

        // Start performance tracking
        $performanceKey = 'discovery_' . md5($context->getCacheKey()->toString());
        $this->performanceCollector?->startTiming(
            $performanceKey,
            PerformanceCategory::DISCOVERY,
            [
                'paths' => $context->paths,
                'scan_type' => $context->scanType->value,
                'use_cache' => $options->useCache,
            ]
        );

        try {
            // Try cache first
            if ($options->useCache && $cached = $this->cacheManager->get($context)) {
                $this->performanceCollector?->increment(
                    'discovery_cache_hits',
                    PerformanceCategory::DISCOVERY
                );
                $this->emitCacheHitEvent($context, $cached);

                return $cached;
            }

            // Cache miss tracking
            if ($options->useCache) {
                $this->performanceCollector?->increment(
                    'discovery_cache_misses',
                    PerformanceCategory::DISCOVERY
                );
            }

            // Start discovery
            $this->emitStartEvent($context);

            // Process files with new architecture
            $registry = $this->performDiscovery($context);

            // Track discovery metrics
            $this->performanceCollector?->recordMetric(
                'discovery_files_processed',
                PerformanceCategory::DISCOVERY,
                $registry->getFileCount()
            );

            $this->performanceCollector?->recordMetric(
                'discovery_total_items',
                PerformanceCategory::DISCOVERY,
                count($registry)
            );

            // Cache results
            if ($options->useCache) {
                $this->cacheManager->store($context, $registry);
            }

            // Complete
            $this->emitCompletedEvent($context, $registry);

            return $registry;

        } catch (Throwable $e) {
            $this->performanceCollector?->increment(
                'discovery_errors',
                PerformanceCategory::DISCOVERY
            );
            $this->emitFailedEvent($context, $e);

            throw $e;
        } finally {
            // End performance tracking
            $this->performanceCollector?->endTiming($performanceKey);
        }
    }

    /**
     * Update cache for specific directory (for incremental updates)
     */
    public function updateDirectory(string $directory): void
    {
        $options = new DiscoveryOptions(
            scanType: ScanType::INCREMENTAL,
            paths: [$directory],
            useCache: false
        );

        $this->discoverWithOptions($options);
    }

    /**
     * Get health status of all components including memory management
     */
    /**
     * Get health status of all components including memory management
     * @return array<string, mixed>
     */
    public function getHealthStatus(): array
    {
        $memoryStatus = $this->memoryManager->getMemoryStatus();
        $guardStats = $this->memoryGuard->getStatistics();

        return [
            'service' => 'healthy',
            'cache' => $this->cacheManager->getHealthStatus(),
            'memory_management' => [
                'status' => $memoryStatus->status->value,
                'current_usage' => $memoryStatus->currentUsage->toHumanReadable(),
                'memory_limit' => $memoryStatus->memoryLimit->toHumanReadable(),
                'memory_pressure' => $memoryStatus->memoryPressure->toString(),
                'strategy' => $memoryStatus->strategy->value,
                'guard_checks' => $guardStats->totalChecks,
                'emergency_mode' => $guardStats->emergencyMode,
            ],
            'components' => [
                'processing_context' => 'operational',
                'file_processor' => 'operational',
                'visitor_coordinator' => 'operational',
                'cache_manager' => 'operational',
                'memory_manager' => 'operational',
                'memory_guard' => 'operational',
                'adaptive_chunker' => 'operational',
            ],
            'legacy_memory_usage' => $this->memoryMonitor?->getCurrentMemory()->toHumanReadable() ?? 'N/A',
        ];
    }

    /**
     * Get memory management statistics
     */
    /**
     * Get memory management statistics
     * @return array<string, mixed>
     */
    public function getMemoryStatistics(): array
    {
        $memoryStatus = $this->memoryManager->getMemoryStatus();
        $guardStats = $this->memoryGuard->getStatistics();
        $chunkingStats = $this->adaptiveChunker->getPerformanceStatistics();

        return [
            'memory_status' => $memoryStatus->toArray(),
            'guard_statistics' => $guardStats->toArray(),
            'chunking_performance' => $chunkingStats,
            'strategy_description' => $this->memoryManager->getStrategyDescription(),
            'recommendations' => $this->memoryGuard->getRecommendations(),
        ];
    }

    /**
     * Check if rescan is needed
     */
    public function shouldRescan(): bool
    {
        $context = new DiscoveryContext(
            paths: [$this->pathProvider->getBasePath() . '/src'],
            scanType: ScanType::FULL,
            options: new DiscoveryOptions(),
            startTime: $this->clock->now(),
            executionContext: $this->executionContext
        );

        return $this->cacheManager->get($context) === null;
    }

    /**
     * Get processed file count from last discovery
     */
    public function getProcessedFileCount(): int
    {
        // This would need to be tracked in the context
        return 0;
    }

    /**
     * Get cache status including hit rates, size, and health metrics
     */
    public function getCacheStatus(): array
    {
        try {
            $healthStatus = $this->cacheManager->getHealthStatus();
            $cacheMetrics = $this->cacheManager->getCacheMetrics();

            return [
                'health' => $healthStatus,
                'metrics' => $cacheMetrics?->toArray() ?? [],
                'status' => 'available',
            ];
        } catch (\Throwable $e) {
            $this->logger?->error('Failed to get cache status', [
                'error' => $e->getMessage(),
            ]);

            return [
                'error' => $e->getMessage(),
                'status' => 'unavailable',
            ];
        }
    }

    /**
     * Warm cache for specified paths or default framework paths
     * @param array<int, string>|null $paths
     */
    public function warmCache(?array $paths = null): array
    {
        $startTime = microtime(true);

        if ($paths === null) {
            $paths = [
                $this->pathProvider->src(),
            ];
        }

        $warmedCount = 0;
        $errors = [];

        foreach ($paths as $path) {
            try {
                // Trigger discovery - cache wird automatisch befüllt
                $this->discover();
                $warmedCount++;
            } catch (\Throwable $e) {
                $errors[] = "Failed to warm cache for path '{$path}': {$e->getMessage()}";
                $this->logger?->error('Cache warm failed', [
                    'path' => $path,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $duration = microtime(true) - $startTime;

        return [
            'warmed_paths' => $warmedCount,
            'total_paths' => count($paths),
            'duration_ms' => round($duration * 1000, 2),
            'errors' => $errors,
            'cache_status' => $this->getCacheStatus(),
        ];
    }

    /**
     * Clear all discovery cache entries
     */
    public function clearCache(): bool
    {
        try {
            $cleared = $this->cacheManager->clearAll();

            $this->logger?->info('Discovery cache cleared successfully');

            return $cleared;
        } catch (\Throwable $e) {
            $this->logger?->error('Failed to clear cache', [
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /**
     * Perform the actual discovery using new architecture with memory management
     */
    private function performDiscovery(DiscoveryContext $context): DiscoveryRegistry
    {
        $collector = new DiscoveryDataCollector();

        // Check initial memory status
        $initialMemoryStatus = $this->memoryManager->getMemoryStatus();
        $this->logger?->debug('Starting discovery with memory management', LogContext::withData([
            'initial_memory' => $initialMemoryStatus->toArray(),
            'paths' => $context->paths,
        ]));

        // Use adaptive chunked processing if memory management is enabled
        if ($this->configuration->enableMemoryMonitoring) {
            $this->performMemoryManagedDiscovery($context, $collector);
        } else {
            // Fallback to original processing method
            $this->performStandardDiscovery($context, $collector);
        }

        // Create final registry
        $registry = $collector->createRegistry();

        // Final memory status and cleanup
        $finalMemoryStatus = $this->memoryManager->getMemoryStatus();
        $this->logger?->debug('Discovery completed', LogContext::withData([
            'final_memory' => $finalMemoryStatus->toArray(),
            'registry_size' => count($registry),
        ]));

        // Cleanup
        $collector->clear();
        $cleanupResult = $this->memoryManager->performCleanup();

        if ($cleanupResult->wasEffective()) {
            $this->logger?->debug('Final cleanup performed', LogContext::withData([
                'memory_freed' => $cleanupResult->memoryFreed->toHumanReadable(),
                'collected_cycles' => $cleanupResult->collectedCycles,
            ]));
        }

        return $registry;
    }

    /**
     * Perform memory-managed discovery with adaptive chunking
     */
    private function performMemoryManagedDiscovery(DiscoveryContext $context, DiscoveryDataCollector $collector): void
    {
        // Get all files to process
        $allFiles = [];
        foreach ($context->paths as $path) {
            $filePath = FilePath::create($path);
            $files = $this->fileScanner->findFiles($filePath, FilePattern::php());
            $allFiles = array_merge($allFiles, $files->toArray());
        }

        // Create adaptive chunks
        $chunks = $this->adaptiveChunker->createChunks($allFiles);

        $this->logger?->info('Created adaptive chunks for memory-managed processing', LogContext::withData([
            'total_files' => count($allFiles),
            'chunk_count' => $chunks->count(),
            'total_size' => $chunks->getTotalSize()->toHumanReadable(),
        ]));

        // Process chunks with memory monitoring
        $processingResult = $this->adaptiveChunker->processChunks(
            chunks: $chunks,
            processor: function ($chunk) use ($collector) {
                $processedInChunk = 0;

                foreach ($chunk->getFiles() as $file) {
                    // Check memory guard before processing each file
                    $guardResult = $this->memoryGuard->check();

                    // Only stop if we're in CRITICAL memory state and have processed at least some files
                    // This allows processing to continue under normal memory pressure
                    if (! $this->memoryGuard->isSafeToProcess() &&
                        $guardResult->memoryStatus->status === \App\Framework\Discovery\Memory\MemoryStatus::CRITICAL &&
                        $processedInChunk > 0) {
                        $this->logger?->warning('Stopping chunk processing due to CRITICAL memory constraints', LogContext::withData([
                            'file' => $file->getPath(),
                            'processed_in_chunk' => $processedInChunk,
                            'memory_status' => $guardResult->memoryStatus->toArray(),
                        ]));

                        break;
                    }

                    // Process the file - extract classes first
                    $classExtractor = new ClassExtractor($this->fileSystemService ?? new FileSystemService());
                    $classNames = $classExtractor->extractFromFile($file);
                    $fileContext = FileContext::fromFile($file)->withClassNames($classNames);

                    // Set current file in processing context
                    $this->processingContext->setCurrentFile($fileContext);

                    $this->visitorCoordinator->processFile($file, $fileContext, $collector);
                    $processedInChunk++;
                }

                return true; // Indicate successful processing
            },
            progressCallback: function ($processedFiles, $totalFiles, $chunkIndex, $totalChunks) {
                $this->logger?->debug('Processing progress', LogContext::withData([
                    'processed_files' => $processedFiles,
                    'total_files' => $totalFiles,
                    'chunk' => "{$chunkIndex}/{$totalChunks}",
                    'progress' => round(($processedFiles / $totalFiles) * 100, 1) . '%',
                ]));
            }
        );

        $this->logger?->info('Memory-managed processing completed', LogContext::withData($processingResult->toArray()));
    }

    /**
     * Perform standard discovery without advanced memory management
     */
    private function performStandardDiscovery(DiscoveryContext $context, DiscoveryDataCollector $collector): void
    {
        error_log("UnifiedDiscoveryService: performStandardDiscovery starting with paths: " . implode(', ', $context->paths));

        // Process files with the standard file processor and visitor coordinator
        $this->fileProcessor->processDirectories(
            $context->paths,
            $collector,
            function ($file, $fileContext, $collector) {
                // Debug: Log files being processed, specifically looking for RequestFactory
                if (str_contains($file->getPath()->toString(), 'RequestFactory.php')) {
                    error_log("UnifiedDiscoveryService: Processing RequestFactory file: " . $file->getPath()->toString());
                }
                $this->visitorCoordinator->processFile($file, $fileContext, $collector);
            }
        );

        error_log("UnifiedDiscoveryService: performStandardDiscovery completed");
    }

    /**
     * Emit discovery started event
     */
    private function emitStartEvent(DiscoveryContext $context): void
    {
        $this->eventDispatcher?->dispatch(new DiscoveryStartedEvent(
            estimatedFiles: $this->estimateFiles($context->paths),
            directories: $context->paths,
            scanType: $context->scanType,
            timestamp: $this->clock->time()
        ));
    }

    /**
     * Emit discovery completed event
     */
    private function emitCompletedEvent(DiscoveryContext $context, DiscoveryRegistry $registry): void
    {
        // Create ScannerMetrics from context metrics
        $metrics = $context->getMetrics();
        $scannerMetrics = new ScannerMetrics(
            totalFilesScanned: $context->getProcessedFiles(),
            totalDirectoriesScanned: $metrics['directories_scanned'] ?? 0,
            skippedFiles: $metrics['skipped_files'] ?? 0,
            permissionErrors: $metrics['permission_errors'] ?? 0,
            recoverableErrors: $metrics['recoverable_errors'] ?? 0,
            fatalErrors: $metrics['fatal_errors'] ?? 0,
            retryAttempts: $metrics['retry_attempts'] ?? 0,
            memoryStats: ScannerMemoryUsage::current()
        );

        $this->eventDispatcher?->dispatch(new DiscoveryCompletedEvent(
            filesScanned: $context->getProcessedFiles(),
            duration: $context->getDuration($this->clock),
            metrics: $scannerMetrics,
            scanType: $context->scanType,
            timestamp: $this->clock->time()
        ));
    }

    /**
     * Emit discovery failed event
     */
    private function emitFailedEvent(DiscoveryContext $context, Throwable $exception): void
    {
        $this->eventDispatcher?->dispatch(new DiscoveryFailedEvent(
            exception: $exception,
            partialResults: null,
            scanType: $context->scanType,
            timestamp: $this->clock->time()
        ));
    }

    /**
     * Emit cache hit event
     */
    private function emitCacheHitEvent(DiscoveryContext $context, DiscoveryRegistry $registry): void
    {
        $this->eventDispatcher?->dispatch(new CacheHitEvent(
            cacheKey: $context->getCacheKey(),
            itemCount: count($registry),
            cacheAge: Duration::fromSeconds(0), // Would need cache timestamp
            timestamp: $this->clock->time()
        ));
    }

    /**
     * Estimate file count for progress tracking
     */
    /**
     * Estimate file count for progress tracking
     * @param array<int, string> $paths
     */
    private function estimateFiles(array $paths): int
    {
        $count = 0;
        foreach ($paths as $path) {
            try {
                $iterator = new \RecursiveIteratorIterator(
                    new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)
                );
                foreach ($iterator as $file) {
                    if ($file->getExtension() === 'php') {
                        $count++;
                        if ($count > 1000) {
                            return $count; // Stop counting for performance
                        }
                    }
                }
            } catch (\Throwable) {
                // Ignore errors
            }
        }

        return $count;
    }

    /**
     * Test discovery system functionality for health checks
     */
    /**
     * Test discovery system functionality for health checks
     * @return array<string, mixed>
     */
    public function test(): array
    {
        $testResults = [
            'timestamp' => $this->clock->time(),
            'components' => [],
            'overall_status' => 'healthy',
        ];

        try {
            // Test memory manager
            $memoryStatus = $this->memoryManager->getMemoryStatus('health_test');
            $testResults['components']['memory_manager'] = [
                'status' => 'healthy',
                'memory_pressure' => $memoryStatus->memoryPressure->toDecimal(),
                'current_usage' => $memoryStatus->currentUsage->toHumanReadable(),
            ];
        } catch (\Throwable $e) {
            $testResults['components']['memory_manager'] = [
                'status' => 'error',
                'error' => $e->getMessage(),
            ];
            $testResults['overall_status'] = 'warning';
        }

        try {
            // Test cache manager
            $cacheHealth = $this->cacheManager->getHealthStatus();
            $testResults['components']['cache_manager'] = [
                'status' => 'healthy',
                'driver' => $cacheHealth['cache_driver'],
                'memory_aware' => $cacheHealth['memory_aware'],
            ];
        } catch (\Throwable $e) {
            $testResults['components']['cache_manager'] = [
                'status' => 'error',
                'error' => $e->getMessage(),
            ];
            $testResults['overall_status'] = 'warning';
        }

        try {
            // Test memory guard
            $guardStats = $this->memoryGuard->getStatistics();
            $testResults['components']['memory_guard'] = [
                'status' => 'healthy',
                'total_checks' => $guardStats->totalChecks,
                'emergency_mode' => $guardStats->emergencyMode,
            ];
        } catch (\Throwable $e) {
            $testResults['components']['memory_guard'] = [
                'status' => 'error',
                'error' => $e->getMessage(),
            ];
            $testResults['overall_status'] = 'warning';
        }

        try {
            // Test performance collector if available
            if ($this->performanceCollector !== null) {
                $testResults['components']['performance_collector'] = [
                    'status' => 'healthy',
                    'enabled' => $this->performanceCollector->isEnabled(),
                    'active_timers' => count($this->performanceCollector->getActiveTimers()),
                ];
            }
        } catch (\Throwable $e) {
            $testResults['components']['performance_collector'] = [
                'status' => 'error',
                'error' => $e->getMessage(),
            ];
        }

        // Test basic functionality with a minimal discovery
        try {
            $startTime = microtime(true);

            // Create a minimal test context
            $testPath = $this->pathProvider->getBasePath() . '/src/Framework';
            if (is_dir($testPath)) {
                $options = new DiscoveryOptions(
                    scanType: ScanType::FULL,
                    paths: [$testPath],
                    useCache: false
                );

                $context = new DiscoveryContext(
                    paths: [$testPath],
                    scanType: ScanType::FULL,
                    options: $options,
                    startTime: $this->clock->now(),
                    executionContext: $this->executionContext
                );

                // Simple memory guard check
                $this->memoryGuard->check();

                $testResults['components']['basic_functionality'] = [
                    'status' => 'healthy',
                    'test_duration' => round((microtime(true) - $startTime) * 1000, 2) . 'ms',
                    'test_path' => $testPath,
                ];
            }
        } catch (\Throwable $e) {
            $testResults['components']['basic_functionality'] = [
                'status' => 'error',
                'error' => $e->getMessage(),
            ];
            $testResults['overall_status'] = 'unhealthy';
        }

        return $testResults;
    }
}
