"""Preserve completed redo passes and activate a fresh working directory.""" from __future__ import annotations import copy import shutil import uuid from datetime import datetime from typing import Any from copienator import EvaluationWorkspace, atomic_write_json, read_json from copienator.filesystem import staged_files RESTART_WARNING = ( "Appelez « Nouvelle reprise » seulement après avoir importé les résultats " "de la reprise en cours et exécuté « Mettre à jour les copies finales ». " "Cette consigne s’applique aussi à « Refaire la même sélection »." ) def _identifier() -> str: return f"reprise-{datetime.now().astimezone():%Y%m%d-%H%M%S}-{uuid.uuid4().hex[:8]}" def begin_pass( workspace: EvaluationWorkspace, state: dict[str, Any], *, keep_selection: bool, ) -> tuple[dict[str, Any], str]: """Activate a pass atomically with its selection and reset GUI state. Existing review files remain in place. Legacy BRnot is copied once into the archive; failures before activation leave the old pass active. """ selection = read_json(workspace.refaire_file, default=[]) previous = workspace.refaire_session_dir if previous is None and ( workspace.refaire_file.exists() or workspace.annotation_dir("refaire").exists() ): previous = workspace.root / "Reprises" / _identifier() previous.mkdir(parents=True) legacy = workspace.annotation_dir("refaire") if legacy.is_dir(): shutil.copytree(legacy, previous / "BRnot") if previous is not None: atomic_write_json(previous / "refaire.json", selection) atomic_write_json( previous / "progression.json", { name: entry for name, entry in state.get("steps", {}).items() if name.startswith("refaire_") }, ) ident = _identifier() directory = workspace.root / "Reprises" / ident directory.mkdir(parents=True) new_selection = selection if keep_selection else [] updated = copy.deepcopy(state) values = dict( updated.get("steps", {}).get("refaire_selection", {}).get("values", {}) ) values["selection"] = new_selection updated["steps"] = { name: entry for name, entry in updated.get("steps", {}).items() if not name.startswith("refaire_") } updated["steps"]["refaire_selection"] = {"values": values} updated.setdefault("history", []).append( { "step": "refaire_selection", "action": "repeat" if keep_selection else "new", "session": ident, "timestamp": datetime.now().astimezone().isoformat(), } ) atomic_write_json(directory / "refaire.json", new_selection) atomic_write_json(directory / "session.json", {"id": ident, "values": values}) with staged_files(workspace.root) as staging: atomic_write_json(staging / workspace.refaire_file.name, new_selection) atomic_write_json(staging / workspace.gui_state_file.name, updated) atomic_write_json(staging / "refaire-session.json", {"id": ident}) return updated, ident