<?php
declare(strict_types=1);

/**
 * delete_unused.php
 *
 * Löscht Bilddateien aus $imagedir, die in der DB nicht referenziert sind.
 * Sicherheit:
 * - CLI-only (kein Webzugriff)
 * - Pfad-Härtung via realpath()
 * - Dry-Run optional (default)
 *
 * Aufruf:
 *   php delete_unused.php           # Dry-Run (zeigt nur an)
 *   php delete_unused.php --apply   # wirklich löschen
 */

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit('Forbidden');
}

require_once __DIR__ . '/../config/config.php';

function out(string $msg): void
{
    fwrite(STDOUT, $msg . PHP_EOL);
}
function err(string $msg): void
{
    fwrite(STDERR, "ERROR: " . $msg . PHP_EOL);
    exit(1);
}

// Flags
$apply = in_array('--apply', $argv, true);

// DB verbinden
$conn = @new mysqli($GLOBALS['servername'], $GLOBALS['username'], $GLOBALS['password'], $GLOBALS['db']);
if ($conn->connect_error)
    err('DB-Verbindung fehlgeschlagen');

// Bildverzeichnis prüfen/härten
$baseDir = realpath(__DIR__ . '/..');
if ($baseDir === false)
    err('BaseDir nicht gefunden');

$imgDirCfg = rtrim((string) $GLOBALS['imagedir'], '/');
$imgDir = realpath(__DIR__ . '/../' . $imgDirCfg);
if ($imgDir === false)
    err('imagedir nicht gefunden: ' . $imgDirCfg);

// Verhindere, dass außerhalb des Projekts gelöscht wird
if (strpos($imgDir, $baseDir) !== 0)
    err('imagedir liegt außerhalb des Projekts: ' . $imgDir);

// Aus DB: genutzte Dateien (NULL/"" filtern)
$used = [];
$sql = 'SELECT image FROM wishes WHERE image IS NOT NULL AND image <> ""';
$res = $conn->query($sql);
if ($res === false)
    err('Query fehlgeschlagen');

while ($row = $res->fetch_assoc()) {
    $used[] = (string) $row['image'];
}
$res->free();
$conn->close();

// In ein Set packen
$usedSet = array_flip($used);

$deleted = 0;
$kept = 0;
$skipped = 0;

$it = new DirectoryIterator($imgDir);
foreach ($it as $fileinfo) {
    if ($fileinfo->isDot())
        continue;

    $path = $fileinfo->getPathname();
    if ($fileinfo->isDir()) {
        $skipped++;
        out("[skip-dir] " . $path);
        continue;
    }

    $name = $fileinfo->getFilename();

    if (isset($usedSet[$name])) {
        $kept++;
        out("[keep]     " . $name);
        continue;
    }

    // Nicht referenziert -> löschen (oder dry-run)
    if ($apply) {
        if (@unlink($path)) {
            $deleted++;
            out("[delete]   " . $name);
        } else {
            err('Konnte Datei nicht löschen: ' . $path);
        }
    } else {
        out("[dry-run]  " . $name . "  (würde gelöscht)");
    }
}

out("");
out("Summary:");
out("  kept:    {$kept}");
out("  skipped: {$skipped}");
out("  deleted: {$deleted}" . ($apply ? "" : " (dry-run)"));

exit(0);
