"""
python -m wire_band_edge

Run a Wire.Band edge gateway from the command line.

Examples:

    # MQTT bridge → Wire.Band backend
    python -m wire_band_edge \\
        --broker mqtt://localhost:1883 \\
        --topics "sensors/#" "machines/#" \\
        --backend http://my-wireband-server:8000 \\
        --device-id factory-rpi4

    # With delta filtering (suppress readings with <2% change)
    python -m wire_band_edge \\
        --broker mqtt://localhost:1883 \\
        --topics "sensors/#" \\
        --delta-threshold 0.02

    # Authenticated backend
    python -m wire_band_edge \\
        --broker mqtt://localhost:1883 \\
        --topics "#" \\
        --backend https://my-server.com \\
        --api-key YOUR_TOKEN
"""

import argparse
import asyncio
import logging
import sys


def _build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(
        prog="python -m wire_band_edge",
        description="Wire.Band edge gateway — bridge MQTT to a Wire.Band backend.",
    )
    p.add_argument(
        "--broker", "-b",
        default="mqtt://localhost:1883",
        metavar="URL",
        help="MQTT broker URL (default: mqtt://localhost:1883)",
    )
    p.add_argument(
        "--topics", "-t",
        nargs="+",
        default=["#"],
        metavar="TOPIC",
        help="MQTT topic filters (default: #)",
    )
    p.add_argument(
        "--backend",
        default="http://localhost:8000",
        metavar="URL",
        help="Wire.Band backend HTTP URL (default: http://localhost:8000)",
    )
    p.add_argument(
        "--device-id", "-d",
        default="edge-node",
        metavar="ID",
        help="Unique identifier for this gateway (default: edge-node)",
    )
    p.add_argument(
        "--api-key",
        default=None,
        metavar="TOKEN",
        help="Bearer token for backend authentication",
    )
    p.add_argument(
        "--delta-threshold",
        type=float,
        default=0.0,
        metavar="FLOAT",
        help="Suppress numeric readings with fractional change below this value "
             "(0.0 = forward all, 0.02 = suppress if <2%% change, default: 0.0)",
    )
    p.add_argument(
        "--flush-interval",
        type=float,
        default=1.0,
        metavar="SECONDS",
        help="How often to flush buffered events to the backend (default: 1.0)",
    )
    p.add_argument(
        "--flush-batch",
        type=int,
        default=200,
        metavar="N",
        help="Max events per HTTP flush request (default: 200)",
    )
    p.add_argument(
        "--buffer-size",
        type=int,
        default=50_000,
        metavar="N",
        help="Local ring buffer capacity in events (default: 50000)",
    )
    p.add_argument(
        "--log-level",
        default="INFO",
        choices=["DEBUG", "INFO", "WARNING", "ERROR"],
        help="Log level (default: INFO)",
    )
    return p


async def _run(args: argparse.Namespace) -> None:
    from wire_band_edge import WireBandEdgeClient
    from wire_band_edge.mqtt_connector import MQTTConnector

    client = WireBandEdgeClient(
        backend_url=args.backend,
        device_id=args.device_id,
        api_key=args.api_key,
        buffer_size=args.buffer_size,
        flush_interval=args.flush_interval,
        flush_batch=args.flush_batch,
        delta_threshold=args.delta_threshold,
    )
    connector = MQTTConnector(
        broker_url=args.broker,
        delta_threshold=args.delta_threshold,
    )

    logging.info(
        "Wire.Band edge starting: device=%s broker=%s topics=%s backend=%s",
        args.device_id, args.broker, args.topics, args.backend,
    )

    try:
        await client.run_mqtt(connector, topics=args.topics)
    except KeyboardInterrupt:
        pass
    finally:
        logging.info("Shutting down. Final stats: %s", client.stats())


def main() -> None:
    args = _build_parser().parse_args()
    logging.basicConfig(
        level=args.log_level,
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
        datefmt="%H:%M:%S",
    )
    try:
        asyncio.run(_run(args))
    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == "__main__":
    main()
