#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
from pathlib import Path


def split_tal(text: str) -> tuple[list[str], list[str]]:
    lines = text.splitlines()
    for index, line in enumerate(lines):
        if line.strip() == "":
            return lines[:index], lines[index + 1 :]
    return lines, []


def rsync_only_tal(source: Path) -> tuple[str, dict[str, object]]:
    text = source.read_text(encoding="utf-8", errors="replace")
    uri_lines, key_lines = split_tal(text)
    uris = [
        line.strip()
        for line in uri_lines
        if line.strip() and not line.lstrip().startswith("#")
    ]
    rsync_uris = [
        uri for uri in uris
        if uri.lower().startswith("rsync://")
    ]
    if not rsync_uris:
        return text if text.endswith("\n") else text + "\n", {
            "file": source.name,
            "mode": "unchanged_no_rsync_uri",
            "uris": len(uris),
            "rsyncUris": 0,
        }
    out = "\n".join(rsync_uris) + "\n\n" + "\n".join(key_lines).strip() + "\n"
    return out, {
        "file": source.name,
        "mode": "rsync_only",
        "uris": len(uris),
        "rsyncUris": len(rsync_uris),
    }


def collect_tals(tal_dir: Path | None, tals: list[Path]) -> list[Path]:
    paths: list[Path] = []
    if tal_dir is not None:
        paths.extend(sorted(tal_dir.glob("*.tal")))
    paths.extend(tals)
    unique: dict[str, Path] = {}
    for path in paths:
        unique[path.name] = path
    return [unique[name] for name in sorted(unique)]


def main() -> int:
    parser = argparse.ArgumentParser(description="Prepare TALs for local rsync-tree replay.")
    parser.add_argument("--tal-dir", type=Path)
    parser.add_argument("--tal", type=Path, action="append", default=[])
    parser.add_argument("--out-dir", type=Path, required=True)
    parser.add_argument("--summary", type=Path)
    args = parser.parse_args()

    sources = collect_tals(args.tal_dir, args.tal)
    if not sources:
        raise SystemExit("no TAL files provided")

    args.out_dir.mkdir(parents=True, exist_ok=True)
    rows = []
    for source in sources:
        if not source.is_file():
            raise SystemExit(f"TAL file not found: {source}")
        content, row = rsync_only_tal(source)
        (args.out_dir / source.name).write_text(content, encoding="utf-8")
        rows.append(row)

    if args.summary is not None:
        args.summary.parent.mkdir(parents=True, exist_ok=True)
        args.summary.write_text(json.dumps(rows, indent=2, sort_keys=True) + "\n", encoding="utf-8")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
