#!/usr/bin/env python

import sys
import subprocess
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import os
import PropertyManager
import time
import json
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

class SystemManager(dbus.service.Object):
	def __init__(self,bus,name):
		dbus.service.Object.__init__(self,bus,name)
		self.property_manager = PropertyManager.PropertyManager(bus,System.CACHE_PATH)

		## Signal handlers
		bus.add_signal_receiver(self.NewBusHandler,
					dbus_interface = 'org.freedesktop.DBus', 
					signal_name = "NameOwnerChanged")
		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 bus_name in System.SYSTEM_CONFIG.keys():
			sys_state = System.SYSTEM_CONFIG[bus_name]['system_state']
			if (self.system_states.has_key(sys_state) == False):
				self.system_states[sys_state] = []
			self.system_states[sys_state].append(bus_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("INIT")
		print "SystemManager Init Done"

	def SystemStateHandler(self,state_name):
		print "Checking previous state started..."
		i = 0
		started = self.check_state_started()	
		while(i<10 and started == False):
			started = self.check_state_started()	
			i=i+1
			time.sleep(1)	

		if (i == STATE_START_TIMEOUT):
			print "ERROR: Timeout waiting for state to finish: "+self.current_state
			return					

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

		self.current_state = state_name
		
	@dbus.service.method(DBUS_NAME,
		in_signature='ss', out_signature='a{ss}')
	def getObjectFromId(self,category,key):
		bus_name = ""
		obj_path = ""

		if (System.ID_LOOKUP.has_key(category)):
			if (System.ID_LOOKUP[category].has_key(key)):
				obj_path = System.ID_LOOKUP[category][key]
		else:
			print "ERROR: key not found: "+category+","+key

		if (self.bus_name_lookup.has_key(obj_path)):
			bus_name = self.bus_name_lookup[obj_path]
		else:
			print "ERROR: bus name not found for: "+obj_path
		r = { 'bus_name' : bus_name, 'obj_path' : obj_path }
		return r
	
	def start_process(self,bus_name):
		if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
			process_name = self.bin_path+"/"+System.SYSTEM_CONFIG[bus_name]['process_name']
			cmdline = [ ]
			cmdline.append(process_name)
			System.SYSTEM_CONFIG[bus_name]['popen'] = None
			for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
				cmdline.append(instance['name'])
			try:
				print "Starting process: "+" ".join(cmdline)+": "+bus_name
				System.SYSTEM_CONFIG[bus_name]['popen'] = subprocess.Popen(cmdline)
			except Exception as e:
				## TODO: error
				print "ERROR: starting process: "+" ".join(cmdline)

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

	def check_state_started(self):
		r = True
		if (self.current_state == ""):
			return True
		if (self.system_states.has_key(self.current_state)):
			for bus_name in self.system_states[self.current_state]:
				if (System.SYSTEM_CONFIG[bus_name].has_key('popen') == False and
					System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
					r = False
					break;	
		return r
	

	def NewBusHandler(self, bus_name, a, b):
		if (len(b) > 0 and bus_name.find(Openbmc.BUS_PREFIX) == 0):
			start_time = time.time()
			objects = {}
			try:
				Openbmc.get_objs(bus,bus_name,"",objects)
				for instance_name in objects.keys():
					self.bus_name_lookup[objects[instance_name]['PATH']] = bus_name
				end_time = time.time()
				print "Elapsed time was %g seconds" % (end_time - start_time)
				print bus_name

			except:
				pass
			
			if (System.SYSTEM_CONFIG.has_key(bus_name)):
				System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
				for instance_name in objects.keys(): 
					obj_path = objects[instance_name]['PATH']
					for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
						if (instance.has_key('properties') and instance['name'] == instance_name):
							props = instance['properties']
							print "Load Properties: "+obj_path
							self.property_manager.loadProperties(bus_name,obj_path,props)
					## If object has an init method, call it
					for init_intf in objects[instance_name]['INIT']:
						obj = bus.get_object(bus_name,obj_path)
						intf = dbus.Interface(obj,init_intf)
						print "Calling init method: " +obj_path+" : "+init_intf
						intf.init()


	@dbus.service.method(DBUS_NAME,
		in_signature='s', out_signature='sis')
	def gpioInit(self,name):
		gpio_path = ''
		gpio_num = 0
		if (System.GPIO_CONFIG.has_key(name) == False):
			# TODO: Error handling
			print "ERROR: "+name+" not found in GPIO config table"
			return ['',0,'']
		else:
			gpio_num = System.GPIO_CONFIG[name]['gpio_num']

		return [Openbmc.GPIO_DEV, gpio_num, System.GPIO_CONFIG[name]['direction']]

		

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()

