#!/usr/bin/python -u
import sys
import libvirt
from copy import copy

#An object from PhysicalHost consists on a host that has an hypervisor
class PhysicalHost():
	__hypervisorURI = ''
 	hypervisorAddress = ''
	#This constructor receives the host address and the connection type. 
	#There are diferente connection types defined in libvirt documentation
	def __init__(self,address="localhost",connectionType="xen+ssh"):
		self.__setHypervisorAddress(address)
		self.__setHypervisorURIName(connectionType)
		#Conects the hypervisor defined by the URI
		self.hypervisor = libvirt.open(self.__getHypervisorURIName())
		if self.hypervisor == None:
    			print 'Failed to open connection to the hypervisor'
    			sys.exit(1)	

	#Set the host address atribute
        def __setHypervisorAddress(self,addr):
 		self.__hypervisorAddress = addr
	#Get the host address atribute
	def getHypervisorAddress(self):
		return self.__hypervisorAddress
	#Set the URI name used in the connection with the hypervisor
	def __setHypervisorURIName(self,connType):
		self.__hypervisorURI = connType + "://" + self.getHypervisorAddress() + "/"
	#Get the URI name used in the connection with the hypervisor
	def __getHypervisorURIName(self):
		return self.__hypervisorURI
	#Return a list of virtDomain objects that consists on each active domain 
	def getDomainList (self):
		self.__domainList = []
		for self.__domainID in self.hypervisor.listDomainsID(): 
			self.__domainList.append(self.hypervisor.lookupByID(self.__domainID))
		return self.__domainList

	#Return a domain name given a domain ID
	def getDomainName (self,domainID):
		domain = self.hypervisor.lookupByID(domainID)
		return domain.name()

	#Destroy a domain
	def destroyDomain (self,domainID):
		domain = self.hypervisor.lookupByID(domainID)
		domain.destroy()

	#Set the weight of a domain by its ID
	def setSchedParametersWeight (self,weight,domainID):
		try:
			__domain = self.hypervisor.lookupByID(domainID)
		except:
    			print "Failed to find the domain \"%s\"" % (str(domainID))
    			return False
		__param = {}
		__param['weight'] = weight
		__domain.setSchedulerParameters(__param)
		return True
	#Set the cap of a domain by its name
	def setSchedParametersCap (self,cap,domainID):
		try:
			__domain = self.hypervisor.lookupByID(domainID)
		except:
    			print "Failed to find the domain \"%s\"" % (str(domainID))
    			return False
		__param = {}
		__param['cap'] = cap
		__domain.setSchedulerParameters(__param)
		return True

	#Print the SchedulerParameters of the host	 
	def printSchedParameters(self):
		print "%-15s %-5s %-5s %-5s" % ("Name","ID","Cap","Weight")
		for __domain in self.getDomainList():		
			__schedParameterDict = __domain.schedulerParameters()
        		print "%-15s %-5d %-5d %-5d" % (__domain.name(),__domain.ID(),__schedParameterDict['cap'],__schedParameterDict['weight'])

#Represents a virtual router running in a physical Machine

class VirtualRouter():

    def __init__(self,qosInfo,cap,ID,name=''):
		self.setCap(cap)
                self.setID(ID)
                self.setName(name)
                self.setID
                self.insertNewQosDictionary(qosInfo)
                self.__setCurrentSampleNumber(0)
                self.__measurementList = []

    #Insert new Qos dictionary with the new qosInfo
    def insertNewQosDictionary(self,qosInfo):
        self.qosDictionary = qosInfo.copy()

    #Set Virtual Router Cap
    def setCap(self,cap):
        self.cap = cap

    #Set Virtual Router ID
    def setID(self,ID):
        self.ID = ID

    #Set Virtual Router Name
    def setName(self,name):
        self.name = name

    #Set an entry of Qos Dictionary
    def setQosDictionary(self,qosName,qosValue):
        self.qosDictionary[qosName] = qosValue


    #Set a measure in th current sample that isn't added by addMeasurment method.
    #This is useful to evaluate means by an external class
    def setMeasure(self,measureName,measureValue):
        listIndex = (self.getCurrentSampleNumber() - 1)
        self.__measurementList[listIndex][measureName] = measureValue

    #Set current sample Number.     
    def __setCurrentSampleNumber(self,sampleNumber):
        self.currentSampleNumber = sampleNumber


    #Increment current sample Number.
    def __incCurrentSampleNumber(self):
        self.__setCurrentSampleNumber(self.getCurrentSampleNumber()+1)

    #Add a measurement to measurmentList. Each measure is aquire in an instant
    #Each measure has a dictionary with measure name and its corresponding value
    #Ex: measureDictionary[throughput] = 100
    def addMeasurement(self,measureDictionary):
        self.__measurementList.append(measureDictionary)
        self.__incCurrentSampleNumber()

    #Get Virtual Router Cap
    def getCap(self):
        return self.cap

    #Get Virtual Router ID
    def getID(self):
        return self.ID

    #Get Virtual Router Name
    def getName(self):
        return self.name

    #Get an entry the Qos dictionary
    def getQosDictionary(self,qosName):
        return self.qosDictionary[qosName]

    #Get a value of a measure sample in a 'sampleShift' past. 'sampleShift'=0
    #represent the current measure. If fails, it return -1
    def getMeasure(self,measureName,sampleShift):
        listIndex = (self.getCurrentSampleNumber() - sampleShift) - 1
        if (listIndex < 0):
            return -1
        try:
            measureValue = self.__measurementList[listIndex]
            measure = measureValue[measureName]
        except:
            return -1

        return float(measureValue[measureName])

    #Get current sample Number
    def getCurrentSampleNumber(self):
        return self.currentSampleNumber








    