"""Per-task container registry — flock 보조 인덱스.

docker 라벨은 컨테이너 존재 여부의 기준값(SSOT)이지만 tmux session/pane id 나
findings 파일 경로 같은 운영 메타데이터는 추적하지 못한다. 이 모듈은 task root
하위 ``container/registry.json`` 에 그런 보조 정보를 가벼운 dict 로 보관한다.

flock + tmp+``os.replace`` 원자 쓰기 idiom 은 ``json_registry`` 의 공용
Interface 를 사용하고, lock/registry 경로만 ``paths.container_paths()`` 로
해소해 전역 ``~/.okstra/worktrees/registry.json`` 과 분리한다. dict 구조는
``{"services": {<svc>: {session_name, pane_id, findings_path}}}`` 한 가지뿐 —
worktree_registry 의 dataclass 는 복제하지 않는다.
"""
from __future__ import annotations

from pathlib import Path

from .json_registry import load_registry_json, registry_lock, save_registry_json
from . import paths


def _registry_lock(lock_path: Path):
    """``container/registry.json.lock`` 에 대한 배타 flock."""
    return registry_lock(lock_path)


def _load(registry_path: Path) -> dict:
    data = load_registry_json(registry_path, lambda: {"services": {}})
    data.setdefault("services", {})
    return data


def _save(registry_path: Path, data: dict) -> None:
    save_registry_json(registry_path, data)


def reserve(
    project_root: Path, group: str, task_id: str, service: str,
    *, session_name: str, pane_id: str, findings_path: str,
) -> None:
    """``service`` 의 tmux session/pane/findings 메타데이터를 등록한다."""
    cp = paths.container_paths(project_root, group, task_id)
    with _registry_lock(cp["registry_lock"]):
        data = _load(cp["registry"])
        data["services"][service] = {
            "session_name": session_name,
            "pane_id": pane_id,
            "findings_path": findings_path,
        }
        _save(cp["registry"], data)


def lookup(project_root: Path, group: str, task_id: str) -> dict:
    """현재 registry dict 를 돌려준다. 파일 부재 시 ``{"services": {}}``."""
    cp = paths.container_paths(project_root, group, task_id)
    with _registry_lock(cp["registry_lock"]):
        return _load(cp["registry"])


def release(project_root: Path, group: str, task_id: str, service: str) -> None:
    """``service`` 항목 하나만 제거한다(없으면 no-op)."""
    cp = paths.container_paths(project_root, group, task_id)
    with _registry_lock(cp["registry_lock"]):
        data = _load(cp["registry"])
        data["services"].pop(service, None)
        _save(cp["registry"], data)


def clear(project_root: Path, group: str, task_id: str) -> None:
    """모든 service 항목을 비운다."""
    cp = paths.container_paths(project_root, group, task_id)
    with _registry_lock(cp["registry_lock"]):
        _save(cp["registry"], {"services": {}})
