#!/usr/bin/env python3
"""
Migration: chat_backup.jsonl ts-Werte von Container-Uptime-ms auf UNIX-ms umstellen.

Hintergrund: vor dem Fix nutzte _append_chat_backup() `asyncio.get_event_loop().time()`,
was Container-Monotonic ist (bei Restart wieder 0). Mischte sich mit App-side
`Date.now()` (echtes UNIX-ms) → falsche Sortierung in der App-History.

Strategie: ts < 1e12 (keine UNIX-ms) werden umgeschrieben. Anker = file-mtime,
decay 60 Sekunden pro Eintrag rueckwaerts. Datei-Reihenfolge bleibt erhalten
(append-only war chronologisch korrekt, nur ts-Werte waren Unsinn).

Vorhandene UNIX-ms-Eintraege (file_deleted-Marker, neue Eintraege ab Bridge-Fix)
werden unveraendert gelassen.

Idempotent: zweimal laufen lassen ist sicher — beim zweiten Mal sind alle ts
schon UNIX-ms und werden nicht angefasst.

Backup: schreibt erst chat_backup.jsonl.bak, dann atomar replace.
"""

import json
import os
import shutil
import sys
import time
from pathlib import Path

UNIX_MS_THRESHOLD = 10 ** 12  # < 1e12 ms = vor 2001 = unrealistisch fuer UNIX
GAP_SECONDS = 60  # 1 Eintrag pro Minute rueckwaerts ab mtime


def migrate(path: Path) -> None:
    if not path.exists():
        print(f"Datei nicht da: {path}")
        sys.exit(1)

    raw = path.read_text(encoding="utf-8").splitlines()
    entries = []
    for raw_line in raw:
        s = raw_line.strip()
        if not s:
            continue
        try:
            entries.append(json.loads(s))
        except Exception as e:
            print(f"  ueberspringe kaputte Zeile: {e}")
            continue

    if not entries:
        print("Datei leer")
        return

    file_mtime_ms = int(os.path.getmtime(path) * 1000)
    n = len(entries)
    fixed = 0

    # Wir bauen einen Ersatz-ts (file_mtime - gap*minutes_back) nur fuer
    # Eintraege deren ts < UNIX_MS_THRESHOLD. file_deleted etc. mit echtem
    # UNIX-ms bleiben unangetastet.
    for i, entry in enumerate(entries):
        ts = entry.get("ts", 0)
        if not isinstance(ts, (int, float)) or ts < UNIX_MS_THRESHOLD:
            # Synth-ts vergeben: aelteste = mtime - n*gap, neueste = mtime
            new_ts = file_mtime_ms - (n - 1 - i) * GAP_SECONDS * 1000
            entry["ts"] = new_ts
            fixed += 1

    if fixed == 0:
        print(f"Nichts zu migrieren ({n} Eintraege, alle ts schon UNIX-ms)")
        return

    # Backup
    bak = path.with_suffix(path.suffix + ".bak")
    shutil.copy2(path, bak)
    print(f"Backup: {bak}")

    # Atomic rewrite
    tmp = path.with_suffix(path.suffix + ".tmp")
    with open(tmp, "w", encoding="utf-8") as f:
        for entry in entries:
            f.write(json.dumps(entry, ensure_ascii=False) + "\n")
    tmp.replace(path)

    print(f"Migration fertig: {fixed}/{n} ts umgeschrieben")
    print(f"  aelteste neu : {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(entries[0]['ts'] / 1000))}")
    print(f"  neueste neu  : {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(entries[-1]['ts'] / 1000))}")


if __name__ == "__main__":
    default = Path("/var/lib/docker/volumes/aria-agent_aria-shared/_data/config/chat_backup.jsonl")
    path = Path(sys.argv[1]) if len(sys.argv) > 1 else default
    migrate(path)
