#!/usr/bin/python -u

import sys
#from gi.repository import GObject
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import Openbmc

DBUS_NAME = 'org.openbmc.sensor.Power8Virtual'
OBJ_PATH = '/org/openbmc/sensor/virtual/'

class SensorValue(Openbmc.DbusProperties):
	IFACE_NAME = 'org.openbmc.SensorValue'
	def __init__(self):
		Openbmc.DbusProperties.__init__(self)
		self.Set(SensorValue.IFACE_NAME,'units',"")
		self.ObjectAdded(name,SensorValue.IFACE_NAME)
		
	@dbus.service.method(IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		changed = False
		try:
			old_value = self.Get(SensorValue.IFACE_NAME,'value')
			if (value != old_value):
				changed = True
		except:
			changed = True

		if (changed == True):
			self.Set(SensorValue.IFACE_NAME,'value',value)
			self.Changed(self.getValue(),self.getUnits())



	@dbus.service.method(IFACE_NAME,
		in_signature='', out_signature='v')
	def getValue(self):
		return self.Get(SensorValue.IFACE_NAME,'value')

	@dbus.service.method(IFACE_NAME,
		in_signature='', out_signature='s')
	def getUnits(self):
		return self.Get(SensorValue.IFACE_NAME,'units')

	@dbus.service.signal(IFACE_NAME,signature='vs')
	def Changed(self,value,units):
		pass

class VirtualSensor(SensorValue):
	def __init__(self,bus,name):
		SensorValue.__init__(self)
		dbus.service.Object.__init__(self,bus,name)
		self.ObjectAdded(name,SensorValue.IFACE_NAME)

		
CONTROL_IFACE = 'org.openbmc.Control'
class HostStatusSensor(SensorValue):
	def __init__(self,bus,name):
		SensorValue.__init__(self)
		dbus.service.Object.__init__(self,bus,name)

	##override setValue method
	@dbus.service.method(SensorValue.IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		SensorValue.setValue(self,value)
		if (value == "BLAH"):
			self.GotoSystemState("OS_BOOTED")
			
	@dbus.service.signal(CONTROL_IFACE,signature='s')
	def GotoSystemState(self,state):
		pass
		
CONTROL_IFACE = 'org.openbmc.Control'
class BootProgressSensor(SensorValue):
	def __init__(self,bus,name):
		SensorValue.__init__(self)
		dbus.service.Object.__init__(self,bus,name)

	##override setValue method
	@dbus.service.method(SensorValue.IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		SensorValue.setValue(self,value)
		if (value == "FW Progress, Starting OS"):
			self.GotoSystemState("HOST_BOOTED")
			
	@dbus.service.signal(CONTROL_IFACE,signature='s')
	def GotoSystemState(self,state):
		pass
		


				
if __name__ == '__main__':
	
	sensors = {
		'OperatingSystemStatus' : None,
		'BootCount' : None,
		'OccStatus' : None,
	}
	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
	bus = Openbmc.getDBus()
	name = dbus.service.BusName(DBUS_NAME,bus)
	for instance in sensors.keys():
		sensors[instance]= VirtualSensor(bus,OBJ_PATH+instance)

	sensors['HostStatus'] = HostStatusSensor(bus,OBJ_PATH+"HostStatus")
	sensors['BootProgress'] = BootProgressSensor(bus,OBJ_PATH+"BootProgress")
	mainloop = gobject.MainLoop()
   
	## Initialize sensors 
	sensors['BootProgress'].setValue("INACTIVE")
 	sensors['HostStatus'].setValue("OFF")
	sensors['OperatingSystemStatus'].setValue("OFF")
	sensors['BootCount'].setValue(0)
	sensors['OccStatus'].setValue(0)

	print "Starting virtual sensors"
	mainloop.run()

