<?php
/**
 * Sync sito statico da Forgejo
 * Eseguito periodicamente via Scheduled Task Alwaysdata
 */

define('REPO_API', 'https://forgejo.it/api/v1/repos/UTENTE/REPO/commits?limit=1');
define('REPO_URL', 'https://forgejo.it/UTENTE/REPO.git');
define('WWW_PATH', __DIR__ . '/www');
define('HASH_FILE', __DIR__ . '/last_commit.txt');
define('EXCLUDE', ['.git', '.gitignore', 'README.md', 'CHANGELOG.md',
                   'LICENSE.md', '.forgejo', 'deploy']);

function log_msg(string $msg): void {
    echo '[' . date('Y-m-d H:i:s') . '] ' . $msg . PHP_EOL;
}

function get_remote_commit(): ?string {
    $ch = curl_init(REPO_API);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $response = curl_exec($ch);
    curl_close($ch);

    if (!$response) return null;

    $data = json_decode($response, true);
    return $data[0]['sha'] ?? null;
}

function get_local_commit(): ?string {
    if (!file_exists(HASH_FILE)) return null;
    return trim(file_get_contents(HASH_FILE));
}

function update_site(): bool {
    $temp = sys_get_temp_dir() . '/site-update';

    if (is_dir($temp)) {
        exec('rm -rf ' . escapeshellarg($temp));
    }

    log_msg('Clone in corso...');
    exec('git clone --depth 1 ' . escapeshellarg(REPO_URL) . ' '
         . escapeshellarg($temp) . ' 2>&1', $output, $code);

    if ($code !== 0) {
        log_msg('Errore clone: ' . implode("\n", $output));
        return false;
    }

    $copied = 0;
    foreach (scandir($temp) as $item) {
        if ($item === '.' || $item === '..' || in_array($item, EXCLUDE)) {
            continue;
        }

        $src = $temp . '/' . $item;
        $dst = WWW_PATH . '/' . $item;

        if (is_dir($dst))         exec('rm -rf ' . escapeshellarg($dst));
        elseif (file_exists($dst)) unlink($dst);

        if (is_dir($src)) exec('cp -r ' . escapeshellarg($src) . ' ' . escapeshellarg($dst));
        else              copy($src, $dst);

        $copied++;
    }

    exec('rm -rf ' . escapeshellarg($temp));
    log_msg("Completato: $copied elementi copiati");
    return true;
}

// Main
log_msg('=== Controllo aggiornamenti ===');

$remote = get_remote_commit();
if (!$remote) {
    log_msg('Impossibile contattare API Forgejo');
    exit(1);
}

$local = get_local_commit();

if ($remote === $local) {
    log_msg('Nessun aggiornamento');
    exit(0);
}

log_msg('Aggiornamento disponibile...');
if (update_site()) {
    file_put_contents(HASH_FILE, $remote);
    log_msg("Hash salvato: $remote");
} else {
    log_msg('Aggiornamento fallito');
    exit(1);
}