#!/usr/bin/python3
#
# Copyright(C) 2024 Jason D. McCormick
# Distributed under the "3 Clause BSD License"
# See LICENSE.md with the source

import argparse
import logging
import logging.handlers
import signal
import socket
import socketserver
import sys
from wsjt2ffdl import wsjt_decoder, wsjt_handler, wsjt_qso

_BUILD_ID = "@@HEAD-DEVELOP@@"

# Handle Signals
def sigterm_handler(_signo, _stack_frame):
    log.info("exiting on signal %d", _signo)
    sys.exit(0)    
signal.signal(signal.SIGINT, sigterm_handler)
signal.signal(signal.SIGHUP, sigterm_handler)
signal.signal(signal.SIGTERM, sigterm_handler)

# argparse
ap = argparse.ArgumentParser(description="Listen for WSJT-X QSO messages and log them to FFDL")
ap.add_argument("group", type=str, help="Multicast Group IP")
ap.add_argument("url", type=str, help="URL to Firefly FDL API")
ap.add_argument("--port", type=int, help="Multicast port (default 2237)", default=2237)
ap.add_argument("--debug", help="enable debug-level logging output", action="store_true")
ap.add_argument("--debugmodule", type=str, help="enable debugging only for module specified")
ap.add_argument("--version", help="get the version of the software", action="version", version='%(prog)s {}'.format(_BUILD_ID))
args = ap.parse_args()

# Setup Logging
log = logging.getLogger("wsjt2ffdl-listener")
lh = logging.StreamHandler()
lf = logging.Formatter(fmt="%(levelname)s: (%(name)s) %(message)s")
lh.setFormatter(lf)
log.addHandler(lh)

if args.debugmodule:
    mlog = logging.getLogger(args.debugmodule)
else:
    mlog = logging.getLogger("wsjt2ffdl")
mlog.addHandler(lh)

if args.debug:
    log.setLevel(logging.DEBUG)
    mlog.setLevel(logging.DEBUG)
else:
    log.setLevel(logging.INFO)
    mlog.setLevel(logging.INFO)

FFDL_URL = args.url
log.info(f"Server publishing to {FFDL_URL}")

if __name__ == "__main__":
    HOST, PORT = "0.0.0.0", args.port
    GROUP = args.group
    listener = socketserver.UDPServer((HOST, PORT), wsjt_handler.WsjtHandler)
    listener.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    mreq = socket.inet_aton(GROUP) + socket.inet_aton('0.0.0.0')
    listener.socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    listener.ffdl_url = FFDL_URL

    log.info(f"Server listening for {GROUP}:{PORT}")

    try:
        listener.serve_forever()
    finally:
        log.info("UDP listener shutdown on signal")
        listener.shutdown()
        
