#!/usr/bin/env php
<?php

if (PHP_SAPI !== 'cli') {
    fwrite(STDERR, "This updater must run from the CLI.\n");
    exit(1);
}

$installDir = rtrim((string)(getenv('TRUCKWASH_INSTALL_DIR') ?: '/opt/truckwash-edge-agent'), DIRECTORY_SEPARATOR);
$runtimeDir = $installDir . DIRECTORY_SEPARATOR . 'runtime';
$launcherPath = $installDir . DIRECTORY_SEPARATOR . 'gateway-launcher.sh';
$stagedUpdatePath = $runtimeDir . DIRECTORY_SEPARATOR . 'staged-update.json';
$heartbeatPath = $runtimeDir . DIRECTORY_SEPARATOR . 'auto-updater-heartbeat.json';
$intervalSeconds = max(15, (int)(getenv('AUTO_UPDATER_INTERVAL_SECONDS') ?: 30));

if (!is_dir($runtimeDir)) {
    @mkdir($runtimeDir, 0777, true);
}

$writeHeartbeat = static function (array $payload) use ($heartbeatPath): void {
    $payload['updated_at'] = date(DATE_ATOM);
    file_put_contents($heartbeatPath, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL);
};

$writeHeartbeat([
    'status' => 'starting',
    'interval_seconds' => $intervalSeconds,
]);

while (true) {
    $stagedUpdatePresent = is_file($stagedUpdatePath);
    $writeHeartbeat([
        'status' => $stagedUpdatePresent ? 'waiting_for_window' : 'idle',
        'interval_seconds' => $intervalSeconds,
        'staged_update_present' => $stagedUpdatePresent,
    ]);

    if ($stagedUpdatePresent) {
        $writeHeartbeat([
            'status' => 'reconciling',
            'interval_seconds' => $intervalSeconds,
            'staged_update_present' => true,
        ]);

        $output = [];
        $exitCode = 0;
        exec('/bin/bash ' . escapeshellarg($launcherPath) . ' reconcile 2>&1', $output, $exitCode);

        $writeHeartbeat([
            'status' => $exitCode === 0 ? 'idle' : 'error',
            'interval_seconds' => $intervalSeconds,
            'staged_update_present' => is_file($stagedUpdatePath),
            'last_exit_code' => $exitCode,
            'last_output' => implode("\n", array_slice($output, -40)),
            'last_reconciled_at' => date(DATE_ATOM),
        ]);
    }

    sleep($intervalSeconds);
}
