<?php

declare(strict_types=1);

/**
 * Test script for the new DI system in Discovery module
 */

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\Cache\Driver\InMemoryCache;
use App\Framework\Cache\GeneralCache;
use App\Framework\Core\PathProvider;
use App\Framework\DateTime\SystemClock;
use App\Framework\DI\DefaultContainer;
use App\Framework\Discovery\Factory\DiscoveryServiceFactory;
use App\Framework\Discovery\ValueObjects\DiscoveryConfiguration;
use App\Framework\Discovery\ValueObjects\DiscoveryOptions;
use App\Framework\Discovery\ValueObjects\ScanType;
use App\Framework\Filesystem\FileSystemService;
use App\Framework\Logging\DefaultLogger;
use App\Framework\Logging\Handlers\ConsoleHandler;
use App\Framework\Logging\LogLevel;
use App\Framework\Performance\MemoryMonitor;
use App\Framework\Reflection\CachedReflectionProvider;
use App\Framework\Serializer\Php\PhpSerializer;

echo "🔍 Testing New DI System for Discovery Module\n";
echo "=============================================\n";

try {
    // Setup basic dependencies
    $pathProvider = new PathProvider(__DIR__ . '/../..');
    $cacheDriver = new InMemoryCache();
    $serializer = new PhpSerializer();
    $cache = new GeneralCache($cacheDriver, $serializer);
    $clock = new SystemClock();
    $container = new DefaultContainer();

    // Optional dependencies for testing
    $consoleHandler = new ConsoleHandler();
    $logger = new DefaultLogger(LogLevel::INFO, [$consoleHandler]);
    $memoryMonitor = new MemoryMonitor();
    $reflectionProvider = new CachedReflectionProvider();
    $fileSystemService = new FileSystemService();

    // Register optional services in container
    $container->singleton(\App\Framework\Logging\Logger::class, $logger);
    $container->singleton(\App\Framework\Performance\MemoryMonitor::class, $memoryMonitor);
    $container->singleton(\App\Framework\Reflection\ReflectionProvider::class, $reflectionProvider);
    $container->singleton(\App\Framework\Filesystem\FileSystemService::class, $fileSystemService);

    echo "✅ Dependencies initialized\n";

    // Create factory
    $factory = new DiscoveryServiceFactory($container, $pathProvider, $cache, $clock);
    echo "✅ Factory created\n";

    // Test 1: Create service for testing environment
    echo "\n🧪 Test 1: Testing Environment Configuration\n";
    $testingService = $factory->createForTesting([
        $pathProvider->getBasePath() . '/src/Application/Admin',
    ]);
    echo "✅ Testing service created successfully\n";

    // Test 2: Create service for development environment
    echo "\n🧪 Test 2: Development Environment Configuration\n";
    $devService = $factory->createForDevelopment([
        $pathProvider->getBasePath() . '/src/Application/Admin',
    ]);
    echo "✅ Development service created successfully\n";

    // Test 3: Create service with custom configuration
    echo "\n🧪 Test 3: Custom Configuration\n";
    $customConfig = new DiscoveryConfiguration(
        paths: [$pathProvider->getBasePath() . '/src/Application/Admin'],
        useCache: false,
        enablePerformanceTracking: true,
        enableMemoryMonitoring: true,
        maxFilesPerBatch: 25
    );

    $customService = $factory->create($customConfig);
    echo "✅ Custom service created successfully\n";

    // Test 4: Validate dependencies
    echo "\n🧪 Test 4: Dependency Validation\n";
    $issues = $factory->validateDependencies($customConfig);
    if (empty($issues)) {
        echo "✅ All dependencies validated successfully\n";
    } else {
        echo "⚠️ Dependency issues found:\n";
        foreach ($issues as $issue) {
            echo "  - $issue\n";
        }
    }

    // Test 5: Run a quick discovery
    echo "\n🧪 Test 5: Quick Discovery Run\n";
    $startTime = microtime(true);
    $startMemory = memory_get_usage(true);

    $options = new DiscoveryOptions(
        scanType: ScanType::FULL,
        paths: [$pathProvider->getBasePath() . '/src/Application/Admin'],
        useCache: false
    );

    $registry = $testingService->discoverWithOptions($options);

    $endTime = microtime(true);
    $endMemory = memory_get_usage(true);

    echo "✅ Discovery completed successfully!\n";

    // Results
    echo "\n📊 Results:\n";
    echo "  Total items: " . count($registry) . "\n";
    echo "  Attributes: " . count($registry->attributes) . "\n";
    echo "  Routes: " . count($registry->routes) . "\n";
    echo "  Templates: " . count($registry->templates) . "\n";
    echo "  Interfaces: " . count($registry->interfaces) . "\n";

    // Performance
    echo "\n⚡ Performance:\n";
    echo "  Duration: " . round(($endTime - $startTime) * 1000, 2) . "ms\n";
    echo "  Memory used: " . round(($endMemory - $startMemory) / 1024 / 1024, 2) . "MB\n";
    echo "  Peak memory: " . round(memory_get_peak_usage(true) / 1024 / 1024, 2) . "MB\n";

    // Show some sample routes
    $routes = $registry->routes->getAll();
    if (! empty($routes)) {
        echo "\n🛣️ Sample Routes Found:\n";
        foreach (array_slice($routes, 0, 5) as $route) {
            echo "  - {$route->method->value} {$route->path} -> {$route->class->getShortName()}::{$route->handler->toString()}\n";
        }
    }

    echo "\n🎉 All tests passed successfully!\n";
    echo "\n🏆 Key Benefits of New DI System:\n";
    echo "  ✅ Simplified constructor (11 → 6 parameters)\n";
    echo "  ✅ Configuration-driven setup\n";
    echo "  ✅ Environment-aware defaults\n";
    echo "  ✅ Factory pattern for easy creation\n";
    echo "  ✅ Dependency validation\n";
    echo "  ✅ Better testability\n";
    echo "  ✅ Improved maintainability\n";

} catch (Throwable $e) {
    echo "\n❌ Error during testing:\n";
    echo "  Message: " . $e->getMessage() . "\n";
    echo "  File: " . $e->getFile() . ":" . $e->getLine() . "\n";
    echo "  Stack trace:\n" . $e->getTraceAsString() . "\n";
    exit(1);
}
