import logging
import thread
import ConfigParser

from container_manager import create_container_manager
from resource_manager import ResourceManager
from resource_allocation_policies import create_scheduler
from simulation_manager import *

from constants import *

def finish_sim_task(manager, sim_name, sim_id, duration):
	logging.info('logging sim response ' )
	manager.finishAndScheduleSimTask(sim_name, int(sim_id), duration)

# class 
class DDDASManager(object):

	def __init__(self, conf_file):
		self.initialize(conf_file)				
 
	def initialize(self, conf_file):
		logging.info('Initializing System Manager ...')		
		system_conf = ConfigParser.ConfigParser()
		system_conf.read(conf_file)
		self.resource_manager = ResourceManager(self.createContainerManager(system_conf))
		# initialize the host list, can be updated on demand
		logging.info('Refreshing the host list: '  + ' ...')
		self.resource_manager.initializeCluster()
	    	self.policy = self.createScheduler(system_conf)
	    	valid_sims = system_conf.get('SIMULATION_DETAILS', 'VALID_SIMS')
	    	sim_service_freq = float(system_conf.get('SCHEDULING_DETAILS', 'SIM_SCHEDULER_FREQUENCY'))
	    	sim_status_update_freq = float(system_conf.get('SCHEDULING_DETAILS', 'SIM_STATUS_UPDATE_FREQUENCY'))
	    	self.simulation_manager = SimulationManager(valid_sims, self.policy, sim_service_freq, sim_status_update_freq, self.resource_manager)
	    	
	
	def refreshHostList(self):
		self.container_manager.refreshHosts()
		logging.info('Host list refreshed...')
	
	def createScheduler(self, system_conf):		
		policy = system_conf.get('SCHEDULING_DETAILS', 'ALLOCATION_POLICY')
		return create_scheduler(policy)
	
	def createContainerManager(self, host_conf):		
		manager_type = host_conf.get('CLOUD_DETAILS', 'CLOUD_MANAGER')
		ip = host_conf.get('SERVERS', 'CLOUD_MANAGER_IP')
		port = host_conf.get('SERVERS', 'CLOUD_MANAGER_PORT')
		api_key = host_conf.get('SERVERS', 'CLOUD_MANAGER_API_KEY')
		# only needed for Linux container host
		container_host_port = host_conf.get('SERVERS', 'CONTAINER_HOST_PORT') 
		logging.info('Creating Container Manager of type: ' + manager_type + ' ...')
		return create_container_manager(manager_type, ip, port, manager_api_key=api_key, container_host_port=container_host_port)
			
	def admissionControl(self, sim_type, sim_config_file, cpu, sim_count, deadline):
		try:
			sim = self.simulation_manager.createSimulation(sim_type, sim_config_file, int(cpu), int(sim_count), float(deadline))
			resource = self.simulation_manager.determineRequiredResources(sim.getName())
			#logging.debug(str(resource))
			if resource is None:
				return ADMN_CNTRL_NO_CAPACITY
			
			slots_needed = len(resource[0])

			logging.info('check if capacity available')
			capacity_available = self.resource_manager.checkAvailableCapacity(sim.getResourceSize(), slots_needed)
			if capacity_available:
				self.simulation_manager.startSimulation(sim.getName(), slots_needed)
				return sim.getName()
			return ADMN_CNTRL_NO_CAPACITY
				
		except Exception, err:
			logging.error("problem while performing admission control")
			logging.exception(err)
			return ADMN_CNTRL_INCORRECT_CONFIG

	def logSimEnd (self, sim_name, sim_id, duration):
		thread.start_new_thread( finish_sim_task, (self.simulation_manager, sim_name, sim_id, duration, ))
		return "LOGGED" 
	
	def dumpResult (self, sim_name, file_name):
		sim = self.simulation_manager.getSimulation(sim_name)
		if sim is None:
			return "not_found"
		write_result(sim, file_name)
		return "DUMPED" 
