#!/usr/bin/python -u

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

## Abstract class, must subclass
class SensorValue(Openbmc.DbusProperties):
	IFACE_NAME = 'org.openbmc.SensorValue'
	def __init__(self,bus,name):
		#Openbmc.DbusProperties.__init__(self)
		self.Set(SensorValue.IFACE_NAME,'units',"")
		self.Set(SensorValue.IFACE_NAME,'error',False)
		
	@dbus.service.method(IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		self.Set(SensorValue.IFACE_NAME,'value',value)

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

class SensorThresholds(Openbmc.DbusProperties):
	IFACE_NAME = 'org.openbmc.SensorThresholds'
	def __init__(self,bus,name):
		self.Set(SensorThresholds.IFACE_NAME,'thresholds_enabled',False)
		self.Set(SensorThresholds.IFACE_NAME,'emergency_enabled',False)
		self.Set(SensorThresholds.IFACE_NAME,'warning_upper',0)
		self.Set(SensorThresholds.IFACE_NAME,'warning_lower',0)
		self.Set(SensorThresholds.IFACE_NAME,'critical_upper',0)
		self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
		self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
		self.Set(SensorThresholds.IFACE_NAME,'threshold_state',"NORMAL")
		self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
	
	@dbus.service.method(IFACE_NAME,
		in_signature='', out_signature='')
	def resetThresholdState(self):
		self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")

	def check_thresholds(self,value):
		iface = SensorThresholds.IFACE_NAME
		if (self.Get(iface,'thresholds_enabled') == False):
			return False
		rtn = False
		current_state = "NORMAL"
		if (value >= self.properties[iface]['critical_upper']):
			current_state = "CRITICAL"
			rtn = True
		elif (value <= self.properties[iface]['critical_lower']):
			current_state = "CRITICAL"
			rtn = True
		elif (value >= self.properties[iface]['warning_upper']):
			current_state = "WARNING"
			rtn = True
		elif (value <= self.properties[iface]['warning_lower']):
			current_state = "WARNING"
			rtn = True

		if (self.Get(iface,'threshold_state') != current_state and
		 		current_state == "CRITICAL" and
				self.Get(iface,'emergency_enabled') == True):
			self.Emergency()

		self.Set(iface,'threshold_state',current_state)
		worst = self.properties[iface]['worst_threshold_state']
		if (current_state == "CRITICAL" or 
		   (current_state == "WARNING" and worst != "CRITICAL")):
			self.Set(iface,'worst_threshold_state',current_state)

		return rtn

	@dbus.service.signal(IFACE_NAME,signature='')
	def Emergency(self):
		pass


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

class HwmonSensor(SensorValue,SensorThresholds):
	IFACE_NAME = 'org.openbmc.HwmonSensor'
	def __init__(self,bus,name):
		Openbmc.DbusProperties.__init__(self)
		SensorValue.__init__(self,bus,name)
		SensorThresholds.__init__(self,bus,name)
		self.Set(HwmonSensor.IFACE_NAME,'scale',1)
		self.Set(HwmonSensor.IFACE_NAME,'offset',0)
		self.Set(HwmonSensor.IFACE_NAME,'filename','')
		self.value_dirty = False

		# need to cache value to know if changed
		self.value = None
		dbus.service.Object.__init__(self,bus,name)

	@dbus.service.method(SensorValue.IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		self.value_dirty = True
		SensorValue.setValue(self,value)

	## Called by sensor process to update value from polling
	## if returns not None, then sensor process will update hwmon value
	@dbus.service.method(IFACE_NAME,
		in_signature='v', out_signature='(bv)')
	def setByPoll(self,value):
		scale = self.properties[HwmonSensor.IFACE_NAME]['scale']
		offset = self.properties[HwmonSensor.IFACE_NAME]['offset']
		if (self.value_dirty == True):
			## new value externally set, so just return to hwmon
			## process to write value
			self.value_dirty = False
			val = (self.properties[SensorValue.IFACE_NAME]['value']-offset) * scale
			return [True,val]
		else:
			val = (value/scale) + offset
			if (val != self.value):
				SensorValue.setValue(self,val)
				self.check_thresholds(val)
				self.value = val

			return [False,0]
		
CONTROL_IFACE = 'org.openbmc.Control'
class PowerCap(VirtualSensor):
	def __init__(self, bus, name):
		VirtualSensor.__init__(self, bus, name)
		SensorValue.setValue(self, 0)
		self.sysfs_attr = "/sys/class/hwmon/hwmon3/user_powercap"
	##override setValue method
	@dbus.service.method(SensorValue.IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self, value):
		try:
			cmd_str = "echo "+str(value)+" > "+self.sysfs_attr
			ret = subprocess.check_output(cmd_str, shell=True)
		except subprocess.CalledProcessError as powerexc:
			print "Set PowerCap Error", powerexc.returncode,
			powerexc.output
			return
		print "Set PowerCap: ", value
		SensorValue.setValue(self, value)
		
class BootProgressSensor(VirtualSensor):
	def __init__(self,bus,name):
		VirtualSensor.__init__(self,bus,name)
		self.setValue("Off")
		bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")

	def SystemStateHandler(self,state):
		if (state == "HOST_POWERED_OFF"):
			self.setValue("Off")


	##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
		
class OccStatusSensor(VirtualSensor):
	def __init__(self,bus,name):
		## default path. can be override
		self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
		VirtualSensor.__init__(self,bus,name)
		self.setValue("Disabled")
		bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")

	def SystemStateHandler(self,state):
		if (state == "HOST_POWERED_OFF"):
			self.setValue("Disabled")

	##override setValue method
	@dbus.service.method(SensorValue.IFACE_NAME,
		in_signature='v', out_signature='')
	def setValue(self,value):
		if (value == "Enabled"):
			print "Installing OCC device"
			os.system("echo 1 > " +  self.sysfs_attr)
		else:
			print "Deleting OCC device"
			os.system("echo 0 > " +  self.sysfs_attr)
		SensorValue.setValue(self,value)
			
	@dbus.service.signal(CONTROL_IFACE,signature='s')
	def GotoSystemState(self,state):
		pass
	
class BootCountSensor(VirtualSensor):
	def __init__(self,bus,name):
		VirtualSensor.__init__(self,bus,name)
		self.setValue(2)

class OperatingSystemStatusSensor(VirtualSensor):
	def __init__(self,bus,name):
		VirtualSensor.__init__(self,bus,name)
		self.setValue("Off")
		bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")

	def SystemStateHandler(self,state):
		if (state == "HOST_POWERED_OFF"):
			self.setValue("Off")
