using System;
using System.Threading.Tasks;
using UnityEngine;
namespace MyInfoMate.Vr.Net
{
///
/// Le contenu d'un lieu, servi cache d'abord — item E4 du lot XR-4.
///
/// Deux chemins, jamais mélangés :
///
/// - Au démarrage — le cache s'il existe, affiché tout de suite ;
/// le réseau seulement s'il n'y a rien en cache.
/// - Ensuite — un rafraîchissement en tâche de fond, dont l'échec est
/// silencieux : une borne hors ligne affiche son contenu de la veille, et
/// ce n'est pas une erreur à montrer au visiteur.
///
///
/// C'est aussi ce qui rendra la reprise après coupure gratuite : au redémarrage, le
/// cache est déjà là.
///
public class ContentService
{
readonly ApiClient _client;
readonly string _configurationId;
public ContentService(ApiClient client, string configurationId)
{
_client = client;
_configurationId = configurationId;
}
public class Loaded
{
public ConfigurationExport Export;
/// Vrai si le contenu vient du disque et non du serveur.
public bool FromCache;
/// Date du cache servi, pour l'afficher en mode dégradé.
public DateTime? CachedAt;
public string Error;
public bool Ok => Error == null;
}
public async Task LoadAsync()
{
var cached = ContentCache.ReadExport(_configurationId);
if (cached != null)
{
var parsed = ConfigurationExport.Parse(cached);
if (parsed.Ok)
return new Loaded
{
Export = parsed.Value,
FromCache = true,
CachedAt = ContentCache.ExportDate(_configurationId)
};
// Un cache illisible est un cache mort : on ne le garde pas pour
// rejouer le même échec au prochain démarrage.
Debug.LogWarning("[Content] Cache illisible, il est écarté.");
}
return await FetchAsync();
}
///
/// Rafraîchit le cache sans bloquer l'affichage. Renvoie le contenu neuf, ou null
/// si rien n'a changé ou si le serveur n'a pas répondu — dans les deux cas
/// l'appelant garde ce qu'il montre.
///
public async Task RefreshAsync()
{
var before = ContentCache.ReadExport(_configurationId);
var raw = await _client.GetRawAsync(
$"/api/configuration/{_configurationId}/export");
if (!raw.Ok)
{
Debug.Log($"[Content] Rafraîchissement impossible ({raw.Error}) — " +
"le contenu en cache reste affiché.");
return null;
}
if (raw.Value == before) return null;
var parsed = ConfigurationExport.Parse(raw.Value);
if (!parsed.Ok) return null;
ContentCache.WriteExport(_configurationId, raw.Value);
return parsed.Value;
}
async Task FetchAsync()
{
var raw = await _client.GetRawAsync(
$"/api/configuration/{_configurationId}/export");
if (!raw.Ok) return new Loaded { Error = raw.Error };
var parsed = ConfigurationExport.Parse(raw.Value);
if (!parsed.Ok) return new Loaded { Error = parsed.Error };
ContentCache.WriteExport(_configurationId, raw.Value);
return new Loaded { Export = parsed.Value };
}
}
}