/* Recuperación. Hay CUATRO cosas distintas (ver docs/RECOVERY.md): * 1. El proyecto guardado por el usuario (.tgb). * 2. El autoguardado: copia temporal en la carpeta de estado. * 3. La sesión: marcador que permite detectar un cierre inesperado. * 4. Los puntos de recuperación NOMBRADOS: viven dentro del proyecto. */ #ifndef TAHGIBU_RECOVERY_H #define TAHGIBU_RECOVERY_H #include "tahgibu/document.h" #ifdef __cplusplus extern "C" { #endif /* ---------- Puntos de recuperación nombrados ---------- */ #define TGB_MAX_RECOVERY_POINTS 64 #define TGB_RECOVERY_POINT_NAME_MAX 128 typedef struct tgb_recovery_point_info { uint32_t id; char name[TGB_RECOVERY_POINT_NAME_MAX]; int64_t created_unix; bool compatible; /* false: guardado con un formato que no se puede restaurar */ } tgb_recovery_point_info; size_t tgb_recovery_point_count(const tgb_document *doc); tgb_status tgb_recovery_point_info_at(const tgb_document *doc, size_t index, tgb_recovery_point_info *out); /* Nombre único, no vacío, UTF-8 válido. Comparte memoria con el documento * (copy-on-write): solo cuesta lo que luego se edite. */ tgb_status tgb_recovery_point_create(tgb_document *doc, const char *name, uint32_t *out_id); /* Antes de restaurar crea el punto "Antes de restaurar «nombre»" y vacía el * historial ordinario (queda el punto automático para volver). */ tgb_status tgb_recovery_point_restore(tgb_document *doc, uint32_t id); tgb_status tgb_recovery_point_delete(tgb_document *doc, uint32_t id); /* Memoria extra retenida por los puntos (celdas que ya no están en el documento). */ size_t tgb_recovery_points_extra_bytes(const tgb_document *doc); /* ---------- Autoguardado y recuperación de sesión ---------- */ typedef struct tgb_recovery tgb_recovery; typedef struct tgb_recovery_candidate { char autosave_path[512]; char original_path[512]; /* "" si el documento nunca se guardó */ char title[128]; int64_t saved_unix; } tgb_recovery_candidate; /* Abre la gestión de sesión: busca restos de sesiones que terminaron mal y * registra la sesión actual. Los archivos originales nunca se tocan. */ tgb_status tgb_recovery_open(tgb_context *ctx, tgb_recovery **out); /* clean_exit=true: borra marcador y autoguardados de esta sesión. * clean_exit=false: libera memoria pero deja los archivos (simula un cierre inesperado en pruebas). */ void tgb_recovery_close(tgb_recovery *rec, bool clean_exit); size_t tgb_recovery_candidate_count(const tgb_recovery *rec); tgb_status tgb_recovery_candidate_at(const tgb_recovery *rec, size_t index, tgb_recovery_candidate *out); /* Carga el autoguardado en un documento NUEVO (el original no se modifica). */ tgb_status tgb_recovery_candidate_load(tgb_recovery *rec, size_t index, tgb_document **out); /* Borra el autoguardado (solo si el usuario lo decide). */ tgb_status tgb_recovery_candidate_discard(tgb_recovery *rec, size_t index); tgb_status tgb_recovery_attach(tgb_recovery *rec, tgb_document *doc, const char *title); tgb_status tgb_recovery_detach(tgb_recovery *rec, tgb_document *doc); /* borra su autoguardado */ void tgb_recovery_set_interval(tgb_recovery *rec, double seconds); /* por defecto 300 (5 min) */ /* Llamar a menudo con un reloj monotónico en segundos. Autoguarda los * documentos con cambios cuando toca. Si falla (p. ej. disco lleno) devuelve * el error y CONSERVA el autoguardado anterior. */ tgb_status tgb_recovery_tick(tgb_recovery *rec, double now_seconds); tgb_status tgb_recovery_save_now(tgb_recovery *rec, tgb_document *doc); /* Avisa de que el usuario guardó el proyecto: el autoguardado ya no hace falta. */ void tgb_recovery_notify_saved(tgb_recovery *rec, tgb_document *doc); #ifdef __cplusplus } #endif #endif