###################################################
# daqzmqreq.py
# Copyright (c) 2026 Alex Kuryakin daqgroup@mail.ru
###################################################
# Utility to send request to crwdaq - DaqZmq server
# comes from stdin stream and print received reply.
###################################################

import os
import sys
import zmq
import time

version     = "1.0"
script_name = os.path.basename(sys.argv[0])
copy_right  = "2026 Alex Kuryakin daqgroup@mail.ru"

endpoint = "tcp://localhost:4201"

startime = 0    # start time
opverb   = 0    # option --verb
optiming = 0    # option --timing
optimout = 5000 # option --timeout

###################################################
# Send multipart request (from stdin stream lines).
###################################################
def send_stdin_req(socket):
    lines = []
    for line in sys.stdin:
        lines += [ line.encode("utf-8") ]
    socket.send_multipart(lines)
###################################################

###################################################
# Receive server reply and print to stdout stream.
###################################################
def recv_rep_print(socket):
    lines = socket.recv_multipart()
    for line in lines:
        print(line.decode("utf-8"))
###################################################

###################################################
# Print string (msg) to stderr if --verb flag is on
###################################################
def verbose(msg):
    global opverb
    if opverb > 0:
        print(msg,file=sys.stderr)
###################################################

###################################################
# Parse command line arguments
###################################################
def parse_argv():
    argn = 1
    argp = 1
    global opverb
    global endpoint
    global optiming
    global optimout
    if len(sys.argv) > 1:
        for arg in sys.argv[1:]:
            if arg == "--version":
                print(f"{script_name} version {version}")
                sys.exit(0)
                return
            if arg == "--help":
                print(f"{script_name} version {version}")
                print(f"Copyright (c) {copy_right}")
                print(f"Utility to send request to crwdaq - DaqZmq server")
                print(f"comes from stdin stream and print received reply.")
                print(f"")
                print(f"Usage: {script_name} [-options] [endpoint]")
                print(f"       default endpoint is {endpoint}")
                print(f"Options:")
                print(f" --version    print version")
                print(f" --help       print help screen")
                print(f" --verb       set verbose mode")
                print(f" --timeout t  set timeout (t) ms")
                print(f" --timing     calculate response time")
                print(f"")
                print(f"Examples:")
                print(f" echo \"@Ping\" | python3 {script_name} --timing")
                print(f" printf \"@GetTags\\n/.*/\" | python3 {script_name}")
                print(f" echo \"@Help\" | python3 {script_name} --verb --timing --timeout 5000 tcp://localhost:4201")
                sys.exit(0)
                return
            if arg == "--verb":
                argp += 1
                opverb = 1
                verbose(f"Set option --verb")
            if arg == "--timing":
                argp += 1
                optiming = 1
                verbose(f"Set option --timing")
            if arg == "--timeout":
                argp += 2
                optimout = int(sys.argv[argn+1])
                verbose(f"Set option --timeout {optimout}")
            if argn == argp:
                endpoint = sys.argv[argn]
                verbose(f"Set endpoint {endpoint}")
            argn += 1
###################################################


###################################################
def start_timing():
    global startime, optiming
    if optiming > 0:
        startime = time.perf_counter_ns()
###################################################

###################################################
def stop_timing():
    global startime, optiming
    if optiming > 0:
        elapsed = (time.perf_counter_ns() - startime) * 1e-6
        print(f"Response time {elapsed:.3f} ms",file=sys.stderr)
    
###################################################

######
# Main
######

try:
    parse_argv()
    # create socket
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.setsockopt(zmq.RCVTIMEO,optimout)
    socket.setsockopt(zmq.SNDTIMEO,optimout)
    socket.setsockopt(zmq.CONNECT_TIMEOUT,optimout)
    socket.connect(endpoint)
    # make request
    start_timing()
    send_stdin_req(socket)
    recv_rep_print(socket)
    stop_timing()
except Exception as e:
    print(f"Exception {type(e).__module__}.{type(e).__name__}: {str(e)} ({endpoint})",file=sys.stderr)
    sys.exit(1)

#############
# END OF FILE
#############

