using MyInfoMate.Vr.Manifest;
using MyInfoMate.Vr.Scene;
using UnityEngine;
namespace MyInfoMate.Vr.Boot
{
///
/// Point d'entrée de l'étape S2 : la scène n'est plus codée en dur, elle est
/// construite à partir d'un JSON.
///
/// Remplace , à garder côte à côte le temps de valider
/// S1 : l'un prouve la chaîne technique, l'autre prouve le contrat de données.
///
/// Le manifeste est ici un fichier de StreamingAssets, poussé sur le casque à la
/// main (adb push ou MQDH). En S6 il viendra du réseau et du cache disque
/// — et ne changera pas d'une ligne, c'est le but.
///
public class S2Bootstrap : MonoBehaviour
{
[Header("Manifeste dans Assets/StreamingAssets")]
[SerializeField] string manifestFile = "scene.json";
[Header("Langue de démarrage — vide = langue par défaut du manifeste")]
[SerializeField] string language = "";
SceneBuilder _builder;
async void Start()
{
var head = Camera.main != null ? Camera.main.transform : null;
if (head == null)
Debug.LogError("[S2] Aucune caméra active : le rig VR n'est pas dans la scène. " +
"Meta → Tools → Building Blocks → Camera Rig.");
var rig = head != null ? head.root : null;
var url = ManifestUrl();
var result = await ManifestReader.LoadAsync(url);
if (!result.Ok)
{
// Le refus est le livrable : on affiche la phrase, on ne charge rien,
// et on ne laisse pas une scène vide faire croire à une panne.
SceneMessage.Show(result.Error, head);
return;
}
_builder = gameObject.AddComponent();
var chosen = string.IsNullOrEmpty(language) ? result.Manifest.DefaultLanguage : language;
if (!await _builder.BuildAsync(result.Manifest, head, rig, chosen))
SceneMessage.Show("Le décor de cette scène n'a pas pu être chargé.", head);
}
///
/// Un manifeste poussé sur le casque l'emporte sur celui de l'APK :
/// adb push scene.json /sdcard/Android/data/<package>/files/.
///
/// C'est ce qui rend S2 vérifiable. Lu depuis StreamingAssets, le manifeste
/// est dans l'APK : changer une valeur demanderait un rebuild, et le
/// critère « on modifie le JSON, on relance, sans recompiler » n'aurait plus
/// d'objet. En S6 la même priorité vaudra pour le cache disque.
///
string ManifestUrl()
{
var pushed = System.IO.Path.Combine(Application.persistentDataPath, manifestFile);
if (!System.IO.File.Exists(pushed))
return GltfLoader.StreamingAssetsUrl(manifestFile);
Debug.Log($"[S2] Manifeste poussé : {pushed}");
return new System.Uri(pushed).AbsoluteUri;
}
}
}