# @file vuart.py
#
# @brief This class is to execute commands by virtual uart
#
# @author Manuel Castilla
# @date 23/04/2019
#
###########################################################################

from ssh import SshCmd,SshCmdException

## Class Vuart
#
class Vuart ():
    def __init__(self,hostName,userName,password,busId):
        """
		Construcctor

		Args:
			hostName: ip or hostname
			userName: username
			password : password
			busId: bus ID PCIe
		"""
        self.hostName = hostName
        self.userName = userName
        self.password = password
        self.busId = busId
        self.sshCmd = SshCmd()
        self.command = ""
        parse_dev = self.vUartCommand("lspci | grep CERN | cut -f2 -d :").split(".")
        if (len(parse_dev) > 1):
            self.command = "sudo wrpc-vuart -f /sys/bus/pci/devices/0000\:00\:%02x.0/0000" \
                "\:%02x\:%02x.0/resource0 -o 0x20500 -c " % (int(busId,16),int(busId,16),int(parse_dev[0],16))
        else:
            print("Error: Spec does not detected on host: %s" % hostName)
            raise

    def setIp(self,ip):
        """
		Set IP

		Args:
            ip: IP to assing
        Return:
            Result set ip
        Raises:
            error function
		"""
        try:
            command = "ip\ set\ " + str(ip)
            return self.vUartCommand(command)
        except:
            print("Error set ip:",ip)
            raise

    def modeMaster(self):
        """
		Configure the board in master mode

        Return:
            Result mode master
        Raises:
            error function
		"""
        try:
            command = "mode\ master"
            return self.vUartCommand(command)
        except:
            print("Error mode master")
            raise

    def modeSlave(self):
        """
		Configure the board in slave mode

        Return:
            Result mode slave
        Raises:
            error function
		"""
        try:
            command = "mode\ slave"
            return self.vUartCommand(command)
        except:
            print("Error mode slave")
            raise

    def sfpDetect(self):
        """
		Ask SFP value

        Return:
            SFP value
        Raises:
            error function
		"""
        try:
            command = "sfp\ match"
            return self.vUartCommand(command)
        except:
            print("Error sfp detect")
            raise

    def ptpStart(self):
        """
		Start PTP daemon

        Return:
            Result
        Raises:
            error function
		"""
        try:
            command = "ptp\ start"
            return self.vUartCommand(command)
        except:
            print("Error ptp start")
            raise

    def ptpStop(self):
        """
		Stop PTP daemon

        Return:
            Result
        Raises:
            error function
		"""
        try:
            command = "ptp\ stop"
            return self.vUartCommand(command)
        except:
            print("Error ptp stop")
            raise

    def mode(self):
        """
		Ask board mode

        Return:
            Board mode ("master" or "slave")
        Raises:
            error function
		"""
        try:
            command = "mode"
            return self.vUartCommand(command)
        except:
            print("Error mode")
            raise

    def isTrackPhase(self):
        """
		Ask if the slave board is in TRACK_PHASE

        Return:
            True if TRACK_PHASE, False otherwise
        Raises:
            error function
		"""
        try:
            ret = False
            command = "stat\ 1"
            value = self.vUartCommand(command)
            if ("sv:1 ss:'TRACK_PHASE'" in value):
                ret = True

            return ret
        except:
            print("Error track phase")
            raise

    def vUartCommand(self,command):
        """
		Execute a command

		Args:
            command: command to execute
        Raises:
            error function
		"""
        try:
            uartCommand = self.command + command
            ret = self.sshCmd.exec(self.hostName,uartCommand,self.userName,self.password)
            if ("Unrecognized command" in ret):
                print(ret)
                raise

            return ret
        except SshCmdException as e:
            self.sshCmd.printSshErrorCommand(e.strError) #print error command
            cleanup()
            raise
