import os
import socket
from opcua_subscriber.opcua_subscribe import opcua_pack
from asyncua_server import st
import threading
import yaml

if(os.path.isfile("opc_ua_receiver_config.yaml")):
    yamlfile=open("opc_ua_receiver_config.yaml")
    data = yaml.load(yamlfile, Loader=yaml.FullLoader)
    Endpoint_Url = data["configuration"]["endpoint_url"]
    Namespace_Server = data["configuration"]["namespace_server"]
    udp_hash_receiver_ip=data["configuration"]["udp_hash_receiver_ip"]
    udp_hash_receiver_port=data["configuration"]["udp_hash_receiver_port"]
    localIP = data["configuration"]["udp_ip"]
    localPort = data["configuration"]["udp_port"]


opua=None
sock=None
def start_server():
    global sock
    global opua
    try:
        opua=opcua_pack()
        sock = opua.connect(Endpoint_Url)
    except:
        start_server()
    return opua, sock

def receive_packets():
    print("wait until server starts ...")
    t1 = threading.Thread(target=st,
                          args=(Endpoint_Url, Namespace_Server, udp_hash_receiver_ip, udp_hash_receiver_port,))
    t1.start()
    bufferSize = 1024
    UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    UDPServerSocket.bind((localIP, localPort))
    opua,sock=start_server()
    print("receiving packets ...")
    while (True):
        bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
        message = bytesAddressPair[0]
        datatype,value,ns,nodeid = message.decode().split("&")
        opua.write_opcua_value(sock,ns,nodeid, value,datatype)

def receive_main(_Endpoint_Url,_Namespace_Server,_udp_hash_receiver_ip,_udp_hash_receiver_port,_localIP,_localPort):
    global Endpoint_Url
    global Namespace_Server
    global udp_hash_receiver_ip
    global udp_hash_receiver_port
    global localIP
    global localPort

    Endpoint_Url = _Endpoint_Url
    Namespace_Server = _Namespace_Server
    udp_hash_receiver_ip = _udp_hash_receiver_ip
    udp_hash_receiver_port = _udp_hash_receiver_port
    localIP = _localIP
    localPort = _localPort
    receive_packets()

if __name__ == "__main__":
    receive_packets()