<?php

declare(strict_types=1);

namespace App\Framework\Filesystem;

use App\Framework\Logging\DefaultLogger;
use App\Framework\Logging\LoggerFactory;

/**
 * Decorator für Storage-Implementierungen mit Logging-Unterstützung.
 */
final class LoggableStorage implements Storage
{
    use StorageTrait;

    public PermissionChecker $permissions { get => $this->storage->permissions; }

    public \App\Framework\Async\FiberManager $fiberManager { get => $this->storage->fiberManager; }

    public function __construct(
        private readonly Storage $storage,
        private ?DefaultLogger $logger = null
    ) {
        $this->logger ??= LoggerFactory::getDefaultLogger();
    }

    public function get(string $path): string
    {
        $this->logger->debug("Lese Datei: {$path}");

        return $this->storage->get($path);
    }

    public function put(string $path, string $content): void
    {
        $this->logger->debug("Schreibe Datei: {$path}");
        $this->storage->put($path, $content);
    }

    public function exists(string $path): bool
    {
        $exists = $this->storage->exists($path);
        $this->logger->debug("Prüfe Existenz: {$path} - " . ($exists ? 'existiert' : 'existiert nicht'));

        return $exists;
    }

    public function delete(string $path): void
    {
        $this->logger->debug("Lösche Datei: {$path}");
        $this->storage->delete($path);
    }

    public function copy(string $source, string $destination): void
    {
        $this->logger->debug("Kopiere Datei: {$source} -> {$destination}");
        $this->storage->copy($source, $destination);
    }

    public function size(string $path): int
    {
        $size = $this->storage->size($path);
        $this->logger->debug("Dateigröße: {$path} - {$size} Bytes");

        return $size;
    }

    public function lastModified(string $path): int
    {
        $lastModified = $this->storage->lastModified($path);
        $this->logger->debug("Letzte Änderung: {$path} - " . date('Y-m-d H:i:s', $lastModified));

        return $lastModified;
    }

    public function getMimeType(string $path): string
    {
        $mimeType = $this->storage->getMimeType($path);
        $this->logger->debug("MIME-Typ: {$path} - {$mimeType}");

        return $mimeType;
    }

    public function isReadable(string $path): bool
    {
        $isReadable = $this->storage->isReadable($path);
        $this->logger->debug("Lesbar: {$path} - " . ($isReadable ? 'ja' : 'nein'));

        return $isReadable;
    }

    public function isWritable(string $path): bool
    {
        $isWritable = $this->storage->isWritable($path);
        $this->logger->debug("Schreibbar: {$path} - " . ($isWritable ? 'ja' : 'nein'));

        return $isWritable;
    }

    public function listDirectory(string $directory): array
    {
        $this->logger->debug("Liste Verzeichnis: {$directory}");
        $files = $this->storage->listDirectory($directory);
        $this->logger->debug("Gefundene Dateien: " . count($files));

        return $files;
    }

    public function createDirectory(string $path, int $permissions = 0755, bool $recursive = true): void
    {
        $this->logger->debug("Erstelle Verzeichnis: {$path}");
        $this->storage->createDirectory($path, $permissions, $recursive);
    }

    public function file(string $path): File
    {
        $this->logger->debug("Erstelle File-Objekt: {$path}");

        return $this->storage->file($path);
    }

    public function directory(string $path): Directory
    {
        $this->logger->debug("Erstelle Directory-Objekt: {$path}");

        return $this->storage->directory($path);
    }

    public function batch(array $operations): array
    {
        $this->logger->debug("Führe Batch-Operation aus mit " . count($operations) . " Operationen");
        $results = $this->storage->batch($operations);
        $this->logger->debug("Batch-Operation abgeschlossen");

        return $results;
    }

    public function getMultiple(array $paths): array
    {
        $this->logger->debug("Lese " . count($paths) . " Dateien parallel");
        $results = $this->storage->getMultiple($paths);
        $this->logger->debug("Parallel-Lesen abgeschlossen");

        return $results;
    }

    public function putMultiple(array $files): void
    {
        $this->logger->debug("Schreibe " . count($files) . " Dateien parallel");
        $this->storage->putMultiple($files);
        $this->logger->debug("Parallel-Schreiben abgeschlossen");
    }

    public function getMetadataMultiple(array $paths): array
    {
        $this->logger->debug("Lade Metadaten für " . count($paths) . " Dateien parallel");
        $results = $this->storage->getMetadataMultiple($paths);
        $this->logger->debug("Metadaten-Laden abgeschlossen");

        return $results;
    }
}
