"""Remove repeated soundings from FSL files written by earlier runs of
convert_igra_to_fsl.py (which appended to existing files, so each re-run added
another full copy of every sounding).

    python3 dedupe_fsl.py /var/www/files/upper/2024            # report only
    python3 dedupe_fsl.py /var/www/files/upper/2024 --write    # rewrite, backups in <dir>/.pre-dedupe/

A sounding is the "254" header line plus everything up to the next header.
The first copy of each (hour, day, month, year) is kept; later copies are
dropped. Files without duplicates are left untouched.
"""

from __future__ import annotations

import shutil
import sys
from pathlib import Path


def split_soundings(text: str) -> list[tuple[tuple, str]]:
    out: list[tuple[tuple, str]] = []
    key, buf = None, []
    for line in text.splitlines(keepends=True):
        parts = line.split()
        if parts and parts[0] == "254" and len(parts) >= 5:
            if buf:
                out.append((key, "".join(buf)))
            key, buf = tuple(parts[1:5]), [line]
        elif buf:
            buf.append(line)
    if buf:
        out.append((key, "".join(buf)))
    return out


def dedupe(path: Path, write: bool, backup_dir: Path) -> tuple[int, int]:
    text = path.read_text(errors="replace")
    soundings = split_soundings(text)
    seen: set[tuple] = set()
    kept = []
    for key, block in soundings:
        if key in seen:
            continue
        seen.add(key)
        kept.append(block)
    if len(kept) == len(soundings):
        return len(soundings), len(kept)
    if write:
        backup_dir.mkdir(exist_ok=True)
        shutil.copy2(path, backup_dir / path.name)
        tmp = path.with_name(path.name + ".tmp")
        tmp.write_text("".join(kept))
        shutil.copystat(path, tmp)
        tmp.replace(path)
    return len(soundings), len(kept)


def main() -> None:
    if len(sys.argv) < 2:
        print(__doc__)
        sys.exit(1)
    folder = Path(sys.argv[1])
    write = "--write" in sys.argv
    backup_dir = folder / ".pre-dedupe"
    n_files = n_dup = 0
    for p in sorted(folder.iterdir()):
        if not p.is_file() or not p.name.strip().upper().endswith(".FSL"):
            continue
        n_files += 1
        total, kept = dedupe(p, write, backup_dir)
        if total != kept:
            n_dup += 1
            print(f"{p.name.strip():>20}  {total:>6} records -> {kept:>5} soundings  {'rewritten' if write else 'would rewrite'}")
    print(f"{n_files} files, {n_dup} with duplicates{' (rewritten, originals in ' + str(backup_dir) + ')' if write and n_dup else ''}")


if __name__ == "__main__":
    main()
