import argparse
import socket


def send_txtmsg(dmr_id: int, msg: str, reply: bool, port: int, cai_net: int):
    """Send a DMR text message to the given individual unit ID

    * dmr_id - 24-bit DMR ID of recipient
    * msg - Message string. Will get UTF16 (big endian) encoded
    * reply - If true, listen for a reply text from radio
    * port - UDP port radio listens on for texts
    * cai_net - MSB of IP address. Set in radio codeplug.
    """

    dst_ip = f"{cai_net}.{dmr_id >> 16 & 0xFF}.{dmr_id >> 8 & 0xFF}.{dmr_id & 0xFF}"
    buffer = msg.encode("utf-16-be")

    print(f"Sending '{msg}' to {dst_ip}:{port}")

    sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)

    # Listen for inbound texts on radio interface. May need to be adjusted if
    # you set a non-standard accessory IP in CPS, or use "0.0.0.0" to bind on
    # all IPv4 interfaces.
    sock.bind(("192.168.10.2", port))

    # Transmit the text message
    sock.sendto(buffer, (dst_ip, port))

    response = None
    if reply:
        print("Waiting for reply...")
        reply_data, reply_addr = sock.recvfrom(1024)

        response = (
            reply_addr,
            reply_data.decode("utf-16-be").strip(),
        )

    sock.close()
    return response


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("dmr_id", type=int)
    parser.add_argument("msg", type=str)
    parser.add_argument("--port", type=int, default=5016)
    parser.add_argument("--reply", action="store_true", help="Wait for reply")
    parser.add_argument("--cai_net", type=int, default=12)

    args = parser.parse_args()

    reply = send_txtmsg(args.dmr_id, args.msg, args.reply, args.port, args.cai_net)
    if reply:
        addr, msg = reply
        print(f"From {addr}: '{msg}'")
