#!/usr/bin/env python3
# @file testDIO.py
#
# @brief Check all ports of the boards
#
# @author Manuel Castilla
# @date 25/04/2019
#
###########################################################################

import configparser
from dio import DIO
import time

maxOffset = 0.000000017 #offset 17 nanoseconds


def findTimestamp(listStamp1,listStamp2,offset):
    """
    This function compare two list and search if two timestamps match

    Args:
        listStamp1: first list of timestamps
        listStamp2: second list of timestamps
        offset: maximum offset between each comparison

    Return:
        True if it find a match in the two lists, False otherwise
    """
    for i in listStamp1:
        for j in listStamp2:
            value = i - j
            if (value <= offset and value >= -offset):
                return True

    return False

def tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,channel):
    """
    Try the input and output of channel

    Args:
        hostName1: ip remote host 1
        username1: user name host 1
        password1: password
        interfaceName1 : interface name
        hostName2: ip remote host 2
        username2: user name host 2
        password2: password
        interfaceName2 : interface name
        channel: number of channel to try(0 to 4)
    Raises:
        error channel
    """
    try:
        dio1 = DIO(hostName1,userName1,password1,interfaceName1)
        dio2 = DIO(hostName2,userName2,password2,interfaceName2)
        dio1.configurePorts("pdddd")
        dio2.configurePorts("iiiii")
        dio1.clearTimestamps()
        dio2.clearTimestamps()

        if (channel != 0):
            dio1.armPulse(channel,0.1,"now")
        else:
            time.sleep(2) #wait 2 seconds to ensure some timestamp

        if(findTimestamp(dio1.getTimestamp(channel),dio2.getTimestamp(channel),maxOffset)):
            dio1.configurePorts("iiiii")
            dio2.configurePorts("pdddd")
            dio1.clearTimestamps()
            dio2.clearTimestamps()

            if (channel != 0):
                dio2.armPulse(channel,0.1,"now")
            else:
                time.sleep(2) #wait 2 seconds to ensure some timestamp

            if(findTimestamp(dio1.getTimestamp(channel),dio2.getTimestamp(channel),maxOffset)):
                print("Channel",channel,": ok in host:",hostName1,"and host:",hostName2)
            else:
                raise
        else:
            raise
    except:
        print("Channel",channel,": error in host:",hostName1,"or host:",hostName2)
        raise


#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#

def main(configuration):
    hostName1 = configuration["hostName1"]
    userName1 = configuration["userName1"]
    password1 = configuration["password1"]
    interfaceName1 = configuration["interfaceName1"]
    hostName2 = configuration["hostName2"]
    userName2 = configuration["userName2"]
    password2 = configuration["password2"]
    interfaceName2 = configuration["interfaceName2"]

    try:
        print("Executing DIO test")
        tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,0)
        tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,1)
        tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,2)
        tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,3)
        tryChannel(hostName1,userName1,password1,interfaceName1,hostName2,userName2,password2,interfaceName2,4)
        print("Test DIO: successful")
    except:
        print("Test DIO: error")

if __name__ == '__main__':
    try:
        configuration = {}
        nameConfig = "configuration.cfg"

        config = configparser.ConfigParser()
        config.readfp(open(nameConfig))

        configuration["hostName1"] = config.get('pc1',"hostName")
        configuration["userName1"] = config.get('pc1',"userName")
        configuration["password1"] = config.get('pc1',"password")
        configuration["interfaceName1"] = config.get('pc1',"interfaceName")
        configuration["hostName2"] = config.get('pc2',"hostName")
        configuration["userName2"] = config.get('pc2',"userName")
        configuration["password2"] = config.get('pc2',"password")
        configuration["interfaceName2"] = config.get('pc2',"interfaceName")

        main(configuration)
    except configparser.Error as e:
        print("Error load configuration:",e.message)
