<?php

declare(strict_types=1);

namespace App\Framework\Filesystem\ValueObjects;

/**
 * Konfiguration für das Filesystem-Modul
 *
 * Definiert Storage-Backends, Pfade und weitere Filesystem-Einstellungen
 * entsprechend der Framework-Konventionen.
 */
final readonly class FilesystemConfig
{
    /**
     * @param array<string, array{type: string, path?: string, options?: array<string, mixed>}> $storages
     */
    public function __construct(
        public string $defaultStorage = 'local',
        public array $storages = [
            'local' => [
                'type' => 'file',
                'path' => '/var/www/html/storage',
            ],
        ],
        public bool $enableCompression = false,
        public string $defaultCompressionAlgorithm = 'gzip',
        public bool $enableAtomicWrites = true,
        public bool $enableFileLocking = true,
        public int $defaultFilePermissions = 0644,
        public int $defaultDirectoryPermissions = 0755,
        public bool $createDirectoriesAutomatically = true,
        public int $streamBufferSize = 8192,
        public array $serializers = [
            'json' => 'json',
            'php' => 'php',
            'csv' => 'csv',
        ]
    ) {
    }

    public function getStorageConfig(string $name): array
    {
        if (! isset($this->storages[$name])) {
            throw new \InvalidArgumentException("Storage '{$name}' not configured");
        }

        return $this->storages[$name];
    }

    public function hasStorage(string $name): bool
    {
        return isset($this->storages[$name]);
    }

    public function getDefaultStorageConfig(): array
    {
        return $this->getStorageConfig($this->defaultStorage);
    }

    /**
     * @return array<string>
     */
    public function getAvailableStorages(): array
    {
        return array_keys($this->storages);
    }

    public function isCompressionEnabled(): bool
    {
        return $this->enableCompression && extension_loaded('zlib');
    }

    public function isSerializerAvailable(string $type): bool
    {
        return isset($this->serializers[$type]);
    }

    /**
     * @return array<string>
     */
    public function getAvailableSerializers(): array
    {
        return array_keys($this->serializers);
    }
}
