#!/usr/bin/env python3

import os
import sys
import socket
import json
from socket import socket, AF_INET, SOCK_DGRAM

MY_PORT = 5999
CONTROLLER_PORT = 1500

def getMyIPaddress():
    sx = socket(AF_INET, SOCK_DGRAM)
    sx.connect(("8.8.8.8", 80))
    return sx.getsockname()[0]

def deserialiseModuleInfo(msg):
    """ deserialise a MODULE_INFO message
        return the module name and associated port, or None
    """
    msgAsJson = microjson.from_json(msg)
    if msgAsJson:
        if msgAsJson.get("MessageType") == "MODULE_INFO":
            name = msgAsJson.get("MODULE")
            port = msgAsJson.get("PORT")
            if name and port:
                return name, int(port)
    return None

def sendMessage(ip, port, data):
    """ send any message to an ip+port tuple
    """
    print(ip, port, data)
    send_socket = socket(AF_INET,SOCK_DGRAM)
    send_socket.sendto(data.encode('utf8'), (ip, port))

def getModuleList(target_ip):
    """ send a MODULE_LIST_REQ message
        wait for MODULE_INFO messages
        replies with list of tuples (modulename,port) or None
    """
    result = []
    MSG_MODULE_LIST_REQ =  '{"MessageType":"MODULE_LIST_REQ", "IP":"%s", "Port":"%d" }'
    reply_to_ip = getMyIPaddress()
    recv_socket = socket(AF_INET,SOCK_DGRAM)
    recv_socket.bind(('', MY_PORT))
    msg = MSG_MODULE_LIST_REQ % (reply_to_ip, MY_PORT)
    sendMessage(target_ip, CONTROLLER_PORT, msg)
    while True:
        try:
            recv_socket.settimeout(5)
            msg, addr = recv_socket.recvfrom(32768)
            msgAsJson = json.loads(msg)
            normal_eof = msgAsJson.get("EOF", "0")
            if normal_eof == "1":
                print ("EOF")
                break
            name, port = deserialiseModuleInfo(msgAsJson)
            if name and port:
                result.append((name, port))
        except Exception as e:
            print ("Exception:%s" %(e,))
            break
    return result

def main():
    """ simple test
    """
    # Argument check
    if len(sys.argv)<2:
        sys.stderr.write('usage:' + sys.argv[0] + ' htc_ip_address\n')
        sys.exit(2)

    # Do the work
    print(getModuleList(sys.argv[1]));


if __name__ == "__main__":
    main()
