import os
import socket
import time

GS10 = os.environ.get("GS10_ADDR", "00:13:43:02:E9:EF")
CHANNEL = int(os.environ.get("GS10_CHANNEL", "11"))
CASTER = (os.environ.get("NTRIP_HOST", "ntrip.pavlokostiuk.cloud"), int(os.environ.get("NTRIP_PORT", "2101")))
MOUNT = os.environ.get("NTRIP_MOUNT", "GS10")
SOURCE_PASS = os.environ["NTRIP_SOURCE_PASS"]


def log(*a):
    print(time.strftime("%H:%M:%S"), *a, flush=True)


def open_gs10():
    s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
    s.connect((GS10, CHANNEL))
    return s


def open_caster():
    s = socket.create_connection(CASTER, timeout=15)
    s.sendall(f"SOURCE {SOURCE_PASS} /{MOUNT}\r\nSource-Agent: NTRIP gs10ntrip/1.0\r\n\r\n".encode())
    reply = s.recv(256)
    if not reply.startswith(b"OK") and b" 200 " not in reply:
        raise ConnectionError(f"caster refused: {reply!r}")
    s.settimeout(None)
    return s


def relay():
    gs10, caster = open_gs10(), open_caster()
    log(f"relaying {GS10} ch{CHANNEL} -> {CASTER[0]}:{CASTER[1]}/{MOUNT}")
    total = 0
    with gs10, caster:
        while chunk := gs10.recv(4096):
            caster.sendall(chunk)
            total += len(chunk)
            if total // 100_000 != (total - len(chunk)) // 100_000:
                log(f"{total} bytes sent")
    log("GS10 closed the link")


if __name__ == "__main__":
    while True:
        try:
            relay()
        except OSError as e:
            log("error:", e)
        time.sleep(5)
