# @file dio.py
#
# @brief This class is to interact with the ports of the board
#
# @author Manuel Castilla
# @date 23/04/2019
#
# Copyright (c) 2019 CERN (www.cern.ch).
#
# This file is part of WR Starting Kit project
# (see https://www.ohwr.org/project/wr-starting-kit).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
#(at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################

from ssh import SshCmd,SshCmdException

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

		Args:
			hostName: ip or hostname
			userName: username
			password : password
			busId: number PCIe bus
		"""
        self.hostName = hostName
        self.userName = userName
        self.password = password
        self.busId = busId
        self.command = "sudo wr-dio-cmd /dev/fmc-dio-%i:0" % int(busId,16)
        self.sshCmd = SshCmd()

    def configurePort(self,channel,mode):
        """
		Configure the channel

		Args:
			channel: number 0 to 4
            mode: I/i(Input), 0/1(Output, steady state fixed at 0 low or 1 high),D/d(DIO core output),
            P/p(Channel 0 Output PPS),C/c(Channel 4 Clock Input to PTP core)
        Raises:
            error function
		"""
        try:
            confCommand = self.command + " mode " + str(channel) + " " + mode
            self.execCommand(confCommand)
        except:
            print("Error configure port, channel:",channel,"mode:",mode)
            raise


    def configurePorts(self,modechannels):
        """
		Configure all channels

		Args:
			modechannels: <modech0><modech1><modech2><modech3><modech4>
        Raises:
            error function
		"""
        try:
            confCommand = self.command + " mode " + modechannels
            self.execCommand(confCommand)
        except:
            print("Error configure ports, mode channels:",modechannels)
            raise

    def armPulse(self,channel,period,count):
        """
		generate a pulse in a channel

		Args:
            channel: number 0 to 4
			period: pulse period
            count: string whih number of instances to run
        Raises:
            error function
		"""
        try:
            armCommand = self.command + " pulse " + str(channel) + " " + str(period) + " " + count
            self.execCommand(armCommand)
        except:
            print("Error arm pulse, channel:",channel,"period:",period,"count:",count)
            raise

    def getTimestamp(self,channel):
        """
		Get timestamp of channel

		Args:
            channel: number 0 to 4
        Raises:
            error function
		"""
        try:
            ret = []
            getCommand = self.command + " stamp " + str(channel) + " | cut -f2 -d ,"
            stamp = self.execCommand(getCommand)
            stampSplit = stamp.split()

            for i in stampSplit:
                ret.append(float(i))

            return ret
        except:
            print("Error get timestamp, channel:",channel)
            raise

    def clearTimestamps(self):
        """
		Clear all timestamps

        Raises:
            error function
		"""
        try:
            command = self.command + " stamp &> /dev/null"
            self.execCommand(command)
        except:
            print("Error clear timestamps")
            raise

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

		Args:
            command: command to execute
        Raises:
            error function
		"""
        try:
            return self.sshCmd.exec(self.hostName,command,self.userName,self.password)
        except SshCmdException as e:
            self.sshCmd.printSshErrorCommand(e.strError) #print error command
            cleanup()
            raise

