<?php

declare(strict_types=1);

final class SecurityService
{
    public static function publicError(Throwable $e): string
    {
        $reference = strtoupper(substr(bin2hex(random_bytes(6)), 0, 10));
        error_log(
            '[Globinours ' .
                $reference .
                '] ' .
                get_class($e) .
                ': ' .
                $e->getMessage() .
                ' in ' .
                $e->getFile() .
                ':' .
                $e->getLine(),
        );
        return t('error.unexpected_reference', ['reference' => $reference]);
    }
    public static function hardenRuntimeFiles(): void
    {
        $root = dirname(__DIR__, 2);
        $marker = $root . '/storage/.security-hardened';
        if (is_file($marker) && filemtime($marker) > time() - 86400) {
            return;
        }
        foreach (
            [
                $root . '/data',
                $root . '/storage',
                $root . '/data/private-media',
                $root . '/data/medical-documents',
                $root . '/data/grants',
                $root . '/storage/backups',
                $root . '/storage/logs',
                $root . '/storage/asm3-imports',
            ]
            as $dir
        ) {
            if (is_dir($dir)) {
                @chmod($dir, 0700);
            }
        }
        foreach (
            [
                $root . '/.env',
                $root . '/data/refuge.sqlite',
                $root . '/data/refuge.sqlite-wal',
                $root . '/data/refuge.sqlite-shm',
            ]
            as $file
        ) {
            if (is_file($file)) {
                @chmod($file, 0600);
            }
        }
        foreach (
            [
                'storage/backups/*',
                'storage/logs/*',
                'storage/reports/*',
                'data/private-media/*',
                'data/medical-documents/*',
                'data/grants/*',
            ]
            as $pattern
        ) {
            foreach (glob($root . '/' . $pattern) ?: [] as $file) {
                self::hardenTree($file);
            }
        }
        @touch($marker);
        @chmod($marker, 0600);
    }
    private static function hardenTree(string $path): void
    {
        if (is_file($path)) {
            @chmod($path, 0600);
            return;
        }
        if (!is_dir($path)) {
            return;
        }
        @chmod($path, 0700);
        $it = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST,
        );
        foreach ($it as $item) {
            @chmod($item->getPathname(), $item->isDir() ? 0700 : 0600);
        }
    }
}
