#!/usr/bin/python

# $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/test/end_2_end/test_multi_TANservice_connection.py 435 2018-02-09 08:16:29Z depa $

import sys
import logging
import argparse

import numpy.random as npr

import Nice
import Basda
import BasdaMoccaWheel as moccaW
import BasdaMoccaX as moccaX
import BasdaMoccaXY as moccaXY
import NiceLog
import time


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def main():
    defaultIP = '127.0.0.1'
    defaultPort = 10300;
    defaultServerName = 'TEST_MOTION'
    defaultServiceName = 'TEST_WHEEL'
    defaultResolution = 2048
    defaultDuration = 1
    defaultStartPosition = 1000

    parser = argparse.ArgumentParser(prog='%(prog)s',
                                     description='Moves a motor along a define path')
    parser.add_argument('-i', '--ip',
                        default=defaultIP,
                        help='The IP address of the Server. default: ' + defaultIP)

    parser.add_argument('-p', '--port',
                        default=defaultPort,
                        help='The port of the Server. default: ' + str(defaultPort),
                        type=int)

    parser.add_argument('-svrn', '--servername',
                        default=defaultServerName,
                        help='The name of the Server. default: ' + defaultServerName)

    parser.add_argument('-svcn', '--servicename',
                        default=defaultServiceName,
                        help='The name of the Service. default: ' + defaultServiceName)

    parser.add_argument('-r', '--resolution',
                        default=defaultResolution,
                        help='The motor resolution in steps/rev. default: ' + str(defaultResolution),
                        type=int)

    parser.add_argument('-d', '--duration',
                        default=defaultDuration,
                        help='The trajectory duration in minutes. default: ' + str(defaultDuration),
                        type=float)

    parser.add_argument('-sp', '--startposition',
                        default=defaultStartPosition,
                        help='The trajectory start position in steps. default: ' + str(defaultStartPosition),
                        type=int)

    args = vars(parser.parse_args())

    serviceName = ["TEST_MOTION.WHEELS.APO_W", "TEST_MOTION.WHEELS.ND_W"]
    serverName = ["TEST_MOTION", "TEST_MOTION"]
    ports = [10300,10300]
    # serviceName = ["TEST_APO",
    #                "TEST_ND"]
    # 'TEST_CORO',
                   # 'TEST_LYOT',
                   # 'TEST_SCI1',
                   # 'TEST_SCI2',
                   # 'TEST_DB']


    # ep = "[NAME=" + args['servername'] + ",HOSTNAME=" + args['ip'] + ",PORT=" + str(args['port']) + ",PATH=" + args['servicename'] + ".SVC]"

    # partialEp = "[NAME=" + args['servername'] + ",HOSTNAME=" + args['ip'] + ",PORT=" + str(args['port']) + ",PATH={}.SVC]"
    partialEp = "[NAME={},HOSTNAME=127.0.0.1,PORT={},PATH={}.SVC]"
    # partialEp = "[NAME=" + args['servername'] + ",HOSTNAME=" + args['ip'] + ",PORT=" + str(args['port']) + ",PATH={}]"



    # listEp = [partialEp.format(svc) for svc in serviceName]
    listEp = [partialEp.format(serverName[i], ports[i], serviceName[i]) for i in range(len(serverName))]

    # print "create application with " + ep

    logging.basicConfig(level= logging.DEBUG)
    listWheel = []
    try:
        print "> Connecting with endpoints:"
        # for ep in listEp:
        #     print "> {}".format(ep)
        #     tmpW = Mocca.Wheel.connectWithEndpoint(args['servername'], ep)
        #     listWheel.append(tmpW)
        #     tmpW.readServiceName()
        #     del tmpW
            # listWheel = [Mocca.Wheel.connectWithEndpoint(args['servername'], ep) for ep in listEp]
        # listWheel.append(Mocca.Wheel.connectWithEndpoint(args['servername'], listEp[0]))
        # listWheel.append(Mocca.Wheel.connectWithEndpoint(args['servername'], listEp[1]))
        listWheel.append(Mocca.Wheel.connectWithEndpoint(serviceName[0], listEp[0]))
        listWheel.append(Mocca.Wheel.connectWithEndpoint(serviceName[1], listEp[1]))
        # tmpW.readServiceName()

        for w in listWheel:
            print w.readServiceName()

        for w in listWheel:
            assert w.isReachable(), "Wheel {} not reachable!"###.format(listWheel.index(w))
            logging.debug("service name: {}".format(w.readServiceName()))

        logging.debug("Startup position = {}".format(args['startposition']))
        for w in listWheel:
            print w.readServiceName()
            w.moveAbsoluteStart(args['startposition'])


    except SystemError:
        print "ops"
    # except RuntimeError:
    #     print "runtime error"



def TAN_multi_connect(_dictHosts, _dictServiceNamePorts):
    partialEp = "[NAME={},HOSTNAME={},PORT={},PATH={}.SVC]"
    # listEp = [partialEp.format(serverName[i], ports[i], serviceName[i]) for i in range(len(serverName))]
    listEp = []
    serverName  = []
    port        = []
    Id          = []
    serviceName = []
    for key in _dictHosts.keys():
        onlineFlag = _dictHosts[key][1]
        if  (onlineFlag == 1):
            print ("{}: {}".format(key, _dictHosts[key][0]))
            for svc in _dictServiceNamePorts[key]:
                print "host {}".format(svc[2])
                tmpServerName = svc[0].lower()
                tmpServerName = tmpServerName.replace("-dummy", "-svr-DUMMY")
                serverName.append(tmpServerName)
                port.append(svc[2])
                Id.append(svc[1])
                serviceName.append("{}.{}".format(svc[0], svc[1]))
                print ("{}:{}".format(serverName[-1], serviceName[-1]))
                listEp.append(partialEp.format(serverName[-1], _dictHosts[key][0], port[-1], serviceName[-1]))
            listDevice = []
            listSteps = []
    try:
        for i in range(len(serviceName)):
            # print listEp[i]
            print(serviceName[i])
            # raw_input("> Press key to connect to {} TAN service ...".format(serviceName[i]))
            if (serviceName[i].find("WHEELS") != -1):
                print "> WHEELS: Connecting to {}...".format(serviceName[i])
                listDevice.append(moccaW.Wheel.connectWithEndpoint(Id[i], listEp[i]))
                listSteps.append(npr.randint(0,1985482))
            elif (serviceName[i].find("TT") != -1):
                listDevice.append(moccaXY.XY.connectWithEndpoint(Id[i], listEp[i]))
                # if (serviceName[i].find("BEAM-DUMMY.INBEAM_TT-DUMMY") != -1):
                listSteps.append(Nice.Point(npr.randint(0, 2475804), npr.randint(0, 2475804)))
                print (listSteps[-1])
            else:
                print "> NOT WHEELS: Connecting to {}...".format(serviceName[i])
                listDevice.append(moccaX.X.connectWithEndpoint(Id[i], listEp[i]))
                print ("X connected {}".format(serviceName[i]))
                if ((serviceName[i].find("CAL_MIRROR_DEP-DUMMY") != -1) or
                    (serviceName[i].find("FIBER_DEP-DUMMY") != -1)):
                    listSteps.append(npr.randint(-3640883, 0))
                if (serviceName[i].find("BEAM-DUMMY.INBEAM_DEP-DUMMY") != -1):
                    listSteps.append(npr.randint(-4292060, 4292060))
                if (serviceName[i].find("BEAM-DUMMY.LENS_DEP-DUMMY") != -1):
                    listSteps.append(npr.randint(0, 3605244))


            assert listDevice[-1].isReachable()

        for i in range(len(listDevice)):
            if ((serviceName[i].find("WHEELS") == -1) and (listDevice[i].isAtLimit())):
                print("{}{}{} is at limit!".format(bcolors.WARNING, listDevice[i].readServiceName(), bcolors.ENDC))

        for i in range(len(listDevice)):
            print ("{} Homing ...".format(listDevice[i].readServiceName()))
            listDevice[i].moveToHomeStart()

        for i in range(len(listDevice)):
            print ("{} Wait homing ....".format(listDevice[i].readServiceName()))
            listDevice[i].moveToHomeWait()


        for i in range(len(listDevice)):
            print ("{} Move to absolute position {}".format(listDevice[i].readServiceName(), listSteps[i]))
            listDevice[i].moveAbsoluteStart(listSteps[i])

        for i in range(len(listDevice)):
            listDevice[i].moveAbsoluteWait()

    except SystemError as error:
        print "TANconnect to {} failed for : {}".format(_serviceName, error)


if __name__ == "__main__":
    main()
