#!/usr/bin/python -u

import sys
import subprocess
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import os
import time
import PropertyCacher
import Openbmc

if (len(sys.argv) < 2):
	print "Usage:  system_manager.py [system name]"
	exit(1)

System = __import__(sys.argv[1])
import Openbmc

DBUS_NAME = 'org.openbmc.managers.System'
OBJ_NAME = '/org/openbmc/managers/System'
HEARTBEAT_CHECK_INTERVAL = 20000
STATE_START_TIMEOUT = 10
INTF_SENSOR = 'org.openbmc.SensorValue'
INTF_ITEM = 'org.openbmc.InventoryItem'
INTF_CONTROL = 'org.openbmc.Control'


class SystemManager(dbus.service.Object):
	def __init__(self,bus,name):
		dbus.service.Object.__init__(self,bus,name)

		bus.add_signal_receiver(self.NewObjectHandler,
			signal_name = "ObjectAdded", sender_keyword = 'bus_name')
		bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")

		self.current_state = ""
		self.system_states = {}
		self.bus_name_lookup = {}
		self.bin_path = os.path.dirname(os.path.realpath(sys.argv[0]))

		for name in System.APPS.keys():
			sys_state = System.APPS[name]['system_state']
			if (self.system_states.has_key(sys_state) == False):
				self.system_states[sys_state] = []
			self.system_states[sys_state].append(name)
	
		## replace symbolic path in ID_LOOKUP
		for category in System.ID_LOOKUP:
			for key in System.ID_LOOKUP[category]:
				val = System.ID_LOOKUP[category][key]
				new_val = val.replace("<inventory_root>",System.INVENTORY_ROOT)
				System.ID_LOOKUP[category][key] = new_val
	
		self.SystemStateHandler(System.SYSTEM_STATES[0])

		if not os.path.exists(PropertyCacher.CACHE_PATH):
			print "Creating cache directory: "+PropertyCacher.CACHE_PATH
   			os.makedirs(PropertyCacher.CACHE_PATH)

		print "SystemManager Init Done"


	def SystemStateHandler(self,state_name):
		## clearing object started flags
		try:
			for obj_path in System.EXIT_STATE_DEPEND[self.current_state]:
				System.EXIT_STATE_DEPEND[self.current_state][obj_path] = 0
		except:
			pass

		print "Running System State: "+state_name
		if (self.system_states.has_key(state_name)):
			for name in self.system_states[state_name]:
				self.start_process(name)
		
		if (state_name == "BMC_INIT"):
			## Add poll for heartbeat
	    		gobject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check)
		
		try:	
			cb = System.ENTER_STATE_CALLBACK[state_name]
			for methd in cb.keys():
				obj = bus.get_object(cb[methd]['bus_name'],cb[methd]['obj_name'])
				method = obj.get_dbus_method(methd,cb[methd]['interface_name'])
				method()
		except:
			pass

		self.current_state = state_name

	def gotoNextState(self):
		s = 0
		for i in range(len(System.SYSTEM_STATES)):
			if (System.SYSTEM_STATES[i] == self.current_state):
				s = i+1
	
		if (s == len(System.SYSTEM_STATES)):
			print "ERROR SystemManager: No more system states"
		else:
			new_state_name = System.SYSTEM_STATES[s]
			print "SystemManager Goto System State: "+new_state_name
			self.SystemStateHandler(new_state_name)
	
	
	@dbus.service.method(DBUS_NAME,
		in_signature='', out_signature='s')
	def getSystemState(self):
		return self.current_state

	def doObjectLookup(self,category,key):
		bus_name = ""
		obj_path = ""
		intf_name = INTF_ITEM
		try:
			obj_path = System.ID_LOOKUP[category][key]
			bus_name = self.bus_name_lookup[obj_path]
			parts = obj_path.split('/')
			if (parts[3] == 'sensor'):
				intf_name = INTF_SENSOR
		except Exception as e:
			print "ERROR SystemManager: "+str(e)+" not found in lookup"

		return [bus_name,obj_path,intf_name]

	@dbus.service.method(DBUS_NAME,
		in_signature='ss', out_signature='(sss)')
	def getObjectFromId(self,category,key):
		return self.doObjectLookup(category,key)

	@dbus.service.method(DBUS_NAME,
		in_signature='sy', out_signature='(sss)')
	def getObjectFromByteId(self,category,key):
		byte = int(key)
		return self.doObjectLookup(category,byte)
	
	def start_process(self,name):
		if (System.APPS[name]['start_process'] == True):
			app = System.APPS[name]
			process_name = self.bin_path+"/"+app['process_name']
			cmdline = [ ]
			cmdline.append(process_name)
			if (app.has_key('args')):
				for a in app['args']:
					cmdline.append(a)
			try:
				print "Starting process: "+" ".join(cmdline)+": "+name
				if (app['monitor_process'] == True):
					app['popen'] = subprocess.Popen(cmdline)
				else:
					subprocess.Popen(cmdline)
					
			except Exception as e:
				## TODO: error
				print "ERROR: starting process: "+" ".join(cmdline)

	def heartbeat_check(self):
		for name in System.APPS.keys():
			app = System.APPS[name]
			if (app['start_process'] == True and app.has_key('popen')):
				##   make sure process is still alive
				p = app['popen']
				p.poll()
				if (p.returncode != None):
					print "Process for "+name+" appears to be dead"
					self.start_process(name)
	
		return True

	def NewObjectHandler(self,obj_path, interface_name, bus_name = None):
		if (self.bus_name_lookup.has_key(obj_path)):
			if (self.bus_name_lookup[obj_path] == bus_name):
				return
		self.bus_name_lookup[obj_path] = bus_name
		print "New object: "+obj_path+" ("+bus_name+")"
		try:
			if (System.EXIT_STATE_DEPEND[self.current_state].has_key(obj_path) == True):
				System.EXIT_STATE_DEPEND[self.current_state][obj_path] = 1
			## check if all required objects are started to move to next state
			state = 1
			for obj_path in System.EXIT_STATE_DEPEND[self.current_state]:
				if (System.EXIT_STATE_DEPEND[self.current_state][obj_path] == 0):
					state = 0
			## all required objects have started so go to next state
			if (state == 1):
				print "All required objects started for "+self.current_state
				self.gotoNextState()
		except:
			pass


	@dbus.service.method(DBUS_NAME,
		in_signature='s', out_signature='sis')
	def gpioInit(self,name):
		gpio_path = ''
		gpio_num = -1
		r = ['',gpio_num,'']
		if (System.GPIO_CONFIG.has_key(name) == False):
			# TODO: Error handling
			print "ERROR: "+name+" not found in GPIO config table"
		else:
			
			gpio_num = -1
			gpio = System.GPIO_CONFIG[name]
			if (System.GPIO_CONFIG[name].has_key('gpio_num')):
				gpio_num = gpio['gpio_num']
			else:
				if (System.GPIO_CONFIG[name].has_key('gpio_pin')):
					gpio_num = System.convertGpio(gpio['gpio_pin'])
				else:
					print "ERROR: SystemManager - GPIO lookup failed for "+name
		
			if (gpio_num != -1):
				r = [Openbmc.GPIO_DEV, gpio_num, gpio['direction']]
		return r

	@dbus.service.method(DBUS_NAME,
		in_signature='s', out_signature='si')
	def hwmonInit(self,name):
		dbus_suffix = ""
		poll_interval = 0
		r = ['',0]
		if (System.HWMON_CONFIG.has_key(name) == False):
			# TODO: Error handling
			print "ERROR: "+name+" not found in HWMON config table"
		else:
			
			hwmon = System.HWMON_CONFIG[name]
			print hwmon
			r = [hwmon['dbus_suffix'], hwmon['poll_interval']]
		return r
		

if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    bus = Openbmc.getDBus()
    name = dbus.service.BusName(DBUS_NAME,bus)
    obj = SystemManager(bus,OBJ_NAME)
    mainloop = gobject.MainLoop()

    print "Running SystemManager"
    mainloop.run()

