<?php

declare(strict_types=1);

namespace App\Framework\CircuitBreaker;

use App\Framework\Cache\Cache;
use App\Framework\Cache\Driver\NullCache;
use App\Framework\Cache\GeneralCache;
use App\Framework\DateTime\Clock;
use App\Framework\DI\Container;
use App\Framework\DI\Initializer;
use App\Framework\HttpClient\HttpClient;
use App\Framework\Logging\Logger;
use App\Framework\Serializer\Json\JsonSerializer;

/**
 * Initializer für Circuit Breaker Services
 */
final readonly class CircuitBreakerInitializer
{
    #[Initializer]
    public function initializeCircuitBreaker(Container $container): void
    {
        // Circuit Breaker Manager with EMERGENCY NullCache to prevent memory issues
        $container->bind(CircuitBreakerManager::class, function (Container $container) {
            // Create a GeneralCache with NullCache driver to implement Cache interface
            $nullCache = new GeneralCache(
                adapter: new NullCache(),
                serializer: new JsonSerializer()
            );

            return CircuitBreakerManager::withDefaults(
                cache: $nullCache, // EMERGENCY: Use NullCache wrapped in GeneralCache
                clock: $container->get(Clock::class),
                logger: $container->get(Logger::class)
            );
        });

        // Standard Circuit Breaker
        $container->bind(CircuitBreaker::class, function (Container $container) {
            return $container->get(CircuitBreakerManager::class)->getCircuitBreaker();
        });

        // Database Circuit Breaker
        $container->bind(DatabaseCircuitBreaker::class, function (Container $container) {
            return new DatabaseCircuitBreaker(
                circuitBreaker: $container->get(CircuitBreaker::class),
                config: CircuitBreakerConfig::forDatabase()
            );
        });

        // HTTP Client Circuit Breaker
        $container->bind(HttpClientCircuitBreaker::class, function (Container $container) {
            return new HttpClientCircuitBreaker(
                circuitBreaker: $container->get(CircuitBreaker::class),
                httpClient: $container->get(HttpClient::class)
            );
        });

        // Circuit Breaker Middlewares
        $container->bind('circuit_breaker_middleware_api', function (Container $container) {
            return CircuitBreakerMiddleware::forApi(
                $container->get(CircuitBreaker::class)
            );
        });

        $container->bind('circuit_breaker_middleware_admin', function (Container $container) {
            return CircuitBreakerMiddleware::forAdmin(
                $container->get(CircuitBreaker::class)
            );
        });
    }
}
