"""Example: tabular interface traffic monitor.

Python port of examples/tab/main.go.

Polls ``/interface/print`` at a configurable interval and prints a
tab-separated table of active interface statistics.

Usage::

    uv run python -m routeros.examples.tab.main --help

    # Default: poll every 1 s, show name + rx/tx bytes/packets
    uv run python -m routeros.examples.tab.main \\
        --address 192.168.1.1:8728 \\
        --username admin \\
        --password ""

    # Custom columns and faster poll
    uv run python -m routeros.examples.tab.main \\
        --properties "name,rx-byte,tx-byte" \\
        --interval 0.5

    # Debug logging
    uv run python -m routeros.examples.tab.main --debug

Press Ctrl+C to stop.
"""

from __future__ import annotations

import argparse
import logging
import signal
import sys
import time

import routeros


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(
        description="Tabular RouterOS interface traffic monitor.",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    p.add_argument("--debug",      action="store_true",                                      help="Enable DEBUG logging")
    p.add_argument("--address",    default="192.168.0.1:8728",                               help="RouterOS address:port")
    p.add_argument("--username",   default="admin",                                           help="Username")
    p.add_argument("--password",   default="",                                                help="Password")
    p.add_argument("--properties", default="name,rx-byte,tx-byte,rx-packet,tx-packet",       help="Comma-separated property list")
    p.add_argument("--interval",   type=float, default=1.0,                                  help="Poll interval in seconds")
    return p


def print_header(properties: list[str]) -> None:
    """Print a column header row."""
    print("\t".join(f"{p:<20}" for p in properties))
    print("-" * (21 * len(properties)))


def main() -> None:
    args = build_parser().parse_args()

    level = logging.DEBUG if args.debug else logging.INFO
    logging.basicConfig(
        level=level,
        format="%(asctime)s %(levelname)-8s %(name)s  %(message)s",
        datefmt="%Y-%m-%dT%H:%M:%S",
    )
    log = logging.getLogger("routeros")

    # Graceful Ctrl+C.
    running = True

    def _on_sigint(sig, frame):
        nonlocal running
        print("\nStopped.")
        running = False
        sys.exit(0)

    signal.signal(signal.SIGINT, _on_sigint)

    try:
        c = routeros.dial(args.address, args.username, args.password, logger=log)
    except Exception as exc:
        log.error("could not connect: %s", exc)
        sys.exit(2)

    properties = [p.strip() for p in args.properties.split(",")]

    with c:
        print_header(properties)
        iteration = 0

        while running:
            try:
                reply = c.run(
                    "/interface/print",
                    "?disabled=false",
                    "?running=true",
                    f"=.proplist={args.properties}",
                )
            except routeros.RouterOSError as exc:
                log.error("could not run: %s", exc)
                sys.exit(2)

            # Reprint header every 20 rows for readability.
            if iteration > 0 and iteration % 20 == 0:
                print()
                print_header(properties)

            for sentence in reply.re:
                row = "\t".join(
                    f"{sentence.map.get(prop, ''):20}" for prop in properties
                )
                print(row)

            print()  # blank line between polls (mirrors Go's fmt.Print("\n"))
            iteration += 1
            time.sleep(args.interval)


if __name__ == "__main__":
    main()
