<?php
declare(strict_types=1);

namespace App\Foundation;

final class CacheManager
{
    public function __construct(private readonly string $directory)
    {
    }

    public function get(string $key, mixed $default = null): mixed
    {
        $file = $this->file($key);
        if (!is_file($file)) return $default;
        $row = require $file;
        if (!is_array($row) || ($row['expires_at'] ?? 0) < time()) {
            @unlink($file);
            return $default;
        }
        return $row['value'] ?? $default;
    }

    public function put(string $key, mixed $value, int $ttlSeconds = 3600): void
    {
        $this->ensureDirectory();
        $payload = ['expires_at' => time() + max(1, $ttlSeconds), 'value' => $value];
        file_put_contents($this->file($key), '<?php return ' . var_export($payload, true) . ';' . PHP_EOL, LOCK_EX);
    }

    public function forget(string $key): void { @unlink($this->file($key)); }

    public function clear(): int
    {
        $count = 0;
        foreach (glob(rtrim($this->directory, '/\\') . '/*.php') ?: [] as $file) {
            if (@unlink($file)) $count++;
        }
        return $count;
    }

    public function directory(): string { return $this->directory; }

    private function file(string $key): string
    {
        return rtrim($this->directory, '/\\') . DIRECTORY_SEPARATOR . hash('sha256', $key) . '.php';
    }

    private function ensureDirectory(): void
    {
        if (!is_dir($this->directory) && !@mkdir($this->directory, 0775, true) && !is_dir($this->directory)) {
            throw new \RuntimeException('Impossible de créer le cache AXIOM.');
        }
    }
}
