<?php

declare(strict_types=1);

namespace App\Framework\Http;

use App\Framework\Config\EnvKey;
use App\Framework\DI\Container;
use App\Framework\DI\Initializer;
use App\Framework\Environment\Environment;
use App\Framework\Http\Middleware\ETagMiddleware;
use App\Framework\Logging\Logger;

/**
 * Initialize ETag management services
 */
final readonly class ETagInitializer
{
    public function __construct(
        private Environment $environment,
        private Container $container
    ) {
    }

    #[Initializer]
    public function createETagManager(): ETagManager
    {
        return new ETagManager(
            enabled: $this->environment->getBool(EnvKey::ETAG_ENABLED, true),
            preferWeakETags: $this->environment->getBool(EnvKey::ETAG_PREFER_WEAK, false)
        );
    }

    #[Initializer]
    public function createETagMiddleware(): ETagMiddleware
    {
        $etagManager = $this->container->get(ETagManager::class);
        $logger = $this->container->has(Logger::class) ? $this->container->get(Logger::class) : null;

        $excludePaths = $this->parseArrayEnvVar(
            $this->environment->get(EnvKey::ETAG_EXCLUDE_PATHS, '/api/health,/favicon.ico,/robots.txt')
        );

        $excludeContentTypes = $this->parseArrayEnvVar(
            $this->environment->get(EnvKey::ETAG_EXCLUDE_CONTENT_TYPES, 'application/json,text/event-stream,application/stream')
        );

        return ETagMiddleware::create(
            etagManager: $etagManager,
            logger: $logger,
            options: [
                'exclude_paths' => $excludePaths,
                'exclude_content_types' => $excludeContentTypes,
                'enabled' => $this->environment->getBool(EnvKey::ETAG_MIDDLEWARE_ENABLED, true),
            ]
        );
    }

    /**
     * Parse comma-separated environment variable into array
     * @return array<int, string>
     */
    private function parseArrayEnvVar(string $value): array
    {
        if (empty($value)) {
            return [];
        }

        return array_map('trim', explode(',', $value));
    }
}
