<?php
class SyncService {
    /**
     * Déclenche le reload Kea selon le mode configuré.
     * Retourne ['success' => bool, 'message' => string].
     */
    public static function sync(): array {
        $freebsdMode = (bool)(int)Settings::get('freebsd_mode', '0');

        try {
            if ($freebsdMode) {
                return self::syncFreeBSD();
            } else {
                return self::syncAlmaLinux();
            }
        } catch (Throwable $e) {
            return ['success' => false, 'message' => 'Exception: ' . $e->getMessage()];
        }
    }

    /** Mode AlmaLinux : appel direct de l'API Kea Control Agent. */
    private static function syncAlmaLinux(): array {
        // Synchronise app_subnets → tables natives Kea (dhcp4_subnet, dhcp4_pool, dhcp4_options)
        try {
            Subnet::syncToKea();
        } catch (Throwable $e) {
            return ['success' => false, 'message' => 'Erreur sync subnets natifs : ' . $e->getMessage()];
        }

        $url     = rtrim(Settings::get('kea_api_url', 'http://localhost:8000'), '/') . '/';
        $payload = json_encode(['command' => 'config-reload', 'service' => ['dhcp4']]);
        $headers = ['Content-Type: application/json'];

        $apiUser = Settings::get('kea_api_user', '');
        if ($apiUser !== '') {
            $token     = base64_encode($apiUser . ':' . Settings::get('kea_api_password', ''));
            $headers[] = 'Authorization: Basic ' . $token;
        }

        $result = self::httpPost($url, $payload, $headers);

        if ($result === false) {
            return ['success' => false, 'message' => 'Impossible de joindre l\'API Kea : ' . $url];
        }

        $data = json_decode($result, true);
        // Kea renvoie un tableau : [{"result": 0, "text": "..."}]
        if (is_array($data) && isset($data[0]['result']) && $data[0]['result'] === 0) {
            return ['success' => true, 'message' => 'Kea config-reload OK'];
        }

        $text = $data[0]['text'] ?? $result;
        return ['success' => false, 'message' => 'Kea API erreur : ' . $text];
    }

    /** Mode FreeBSD : appel au sync_server.py. */
    private static function syncFreeBSD(): array {
        $url   = Settings::get('sync_server_url', 'http://localhost:8765/sync');
        $token = Settings::get('sync_token', '');

        $result = self::httpPost($url, '', [
            'X-Token: ' . $token,
            'Content-Length: 0',
        ]);

        if ($result === false) {
            return ['success' => false, 'message' => 'Impossible de joindre sync_server : ' . $url];
        }

        $data   = json_decode($result, true);
        $status = $data['status'] ?? '';

        if ($status === 'ok') {
            return ['success' => true, 'message' => 'Synchronisation OK'];
        }
        if ($status === 'partial') {
            // Config écrite, mais reload Kea échoué (ex: Kea non démarré)
            return ['success' => false, 'message' => $data['message'] ?? 'Config synchronisée — Kea non joignable'];
        }

        $msg = $data['message'] ?? $result;
        return ['success' => false, 'message' => 'sync_server erreur : ' . $msg];
    }

    /** HTTP POST simple via cURL. Retourne le corps de la réponse ou false. */
    private static function httpPost(string $url, string $body, array $headers = []): string|false {
        if (!function_exists('curl_init')) {
            // Fallback stream context si cURL absent
            $opts = [
                'http' => [
                    'method'  => 'POST',
                    'header'  => implode("\r\n", $headers),
                    'content' => $body,
                    'timeout' => 5,
                    'ignore_errors' => true,
                ],
            ];
            return @file_get_contents($url, false, stream_context_create($opts));
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $body,
            CURLOPT_HTTPHEADER     => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 5,
            CURLOPT_CONNECTTIMEOUT => 3,
        ]);
        $response = curl_exec($ch);
        $err      = curl_errno($ch);
        // curl_close() supprimé : no-op depuis PHP 8.0 (CurlHandle libéré par le GC), déprécié en 8.5

        return $err === 0 ? $response : false;
    }
}
