<?php
// ═══════════════════════════════════════════════════════════════════════════════════════════════
// PURPOSE
//   Small compatibility layer over docker.php — resolves a container's WebUI URL and returns
//   the folder grouping in the shape older callers expect.
//
// DESIGN PRINCIPLES
//   Thin by intent. The folder store and inventory live in docker.php; this file only adapts
//   their output. New work belongs there, not here.
//
//   WebUI resolution reads the dockerMan template, which is where Unraid records the port and
//   path a container's UI actually lives on — not guessed from the published ports.
//
// OPERATIONAL SAFEGUARDS
//   A container with no template, or no WebUI declared, returns empty and simply renders
//   without a link. Absence is normal, not an error.
//
//   Read-only. Resolves and reshapes; the store is written only through docker.php.
//
// EXPORTS
//   vv_container_webui()     WebUI URL for one container, or empty
//   vv_get_docker_folders()  folder grouping in the legacy shape
//
// CONFIGURATION
//   Inherits everything from docker.php — see that file's CONFIGURATION block.
// ═══════════════════════════════════════════════════════════════════════════════════════════════
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/docker.php';

function vv_container_webui(string $name, array $portMap): string {
    $template = '/boot/config/plugins/dockerMan/templates-user/my-' . $name . '.xml';
    if (!file_exists($template)) return '';

    $xml = @file_get_contents($template) ?: '';
    if (!preg_match('/<WebUI>(.*?)<\/WebUI>/s', $xml, $m)) return '';

    $url = trim($m[1]);
    if (!$url) return '';

    $url = str_replace('[IP]', vv_local_ip(), $url);

    // [PORT:XXXX] → mapped host port
    $url = preg_replace_callback('/\[PORT:(\d+)\]/', function($pm) use ($name, $portMap) {
        return $portMap[$name][$pm[1]] ?? $pm[1];
    }, $url);

    return $url;
}

function vv_get_docker_folders(): array {
    // Varaverk's own docker_folders.json is the primary store (see include/docker.php) —
    // reading folder.view3's mirror directly here left this widget empty on any host
    // without that optional third-party plugin installed.
    $folderData = vv_dk_read_json();

    // One docker ps call: names, status, port mappings
    $raw = shell_exec("docker ps -a --format '{{.Names}}\t{{.Status}}\t{{.Ports}}' 2>/dev/null") ?? '';
    $statusMap = [];
    $portMap   = [];
    foreach (explode("\n", trim($raw)) as $line) {
        $parts = explode("\t", $line, 3);
        if (count($parts) < 2) continue;
        [$cname, $status, $ports] = array_pad($parts, 3, '');
        $cname = trim($cname);
        if ($cname === '') continue;
        $statusMap[$cname] = trim($status);
        foreach (explode(',', $ports) as $entry) {
            if (preg_match('/(\d+)->(\d+)\/tcp/', trim($entry), $pm)) {
                $portMap[$cname][$pm[2]] = $pm[1]; // containerPort => hostPort
            }
        }
    }

    $folderContainerNames = [];
    $folders = [];

    foreach ($folderData as $id => $f) {
        $containers = [];
        foreach ($f['containers'] ?? [] as $cname) {
            $folderContainerNames[] = $cname;
            $status  = $statusMap[$cname] ?? '';
            $running = str_starts_with($status, 'Up');
            $containers[] = [
                'name'    => $cname,
                'running' => $running,
                'status'  => $status,
                'webui'   => vv_container_webui($cname, $portMap),
            ];
        }
        usort($containers, fn($a, $b) => $b['running'] <=> $a['running'] ?: strcmp($a['name'], $b['name']));

        $folders[] = [
            'id'         => $id,
            'name'       => $f['name'] ?? 'Unnamed',
            'icon'       => $f['icon'] ?? '',
            'containers' => $containers,
        ];
    }
    usort($folders, fn($a, $b) => strcmp($a['name'], $b['name']));

    $ungrouped = [];
    foreach ($statusMap as $cname => $status) {
        if (in_array($cname, $folderContainerNames, true)) continue;
        $running     = str_starts_with($status, 'Up');
        $ungrouped[] = [
            'name'    => $cname,
            'running' => $running,
            'status'  => $status,
            'webui'   => vv_container_webui($cname, $portMap),
        ];
    }
    usort($ungrouped, fn($a, $b) => strcmp($a['name'], $b['name']));

    return [
        'available' => true,
        'folders'   => $folders,
        'ungrouped' => $ungrouped,
    ];
}
