
def handle(slice):
	from core.models import SiteDeployment,SliceDeployment,Deployment,Network,NetworkSlice,NetworkTemplate
	from collections import defaultdict
	site_deployments = SiteDeployment.objects.all()
	site_deploy_lookup = defaultdict(list)
	for site_deployment in site_deployments:
		site_deploy_lookup[site_deployment.site].append(site_deployment.deployment)
	
	slice_deployments = SliceDeployment.objects.all()
	slice_deploy_lookup = defaultdict(list)
	for slice_deployment in slice_deployments:
		slice_deploy_lookup[slice_deployment.slice].append(slice_deployment.deployment)
	
	all_deployments = Deployment.objects.all() 
	# slices are added to all deployments for now
	expected_deployments = all_deployments
	#expected_deployments = site_deploy_lookup[slice.site]
	for expected_deployment in expected_deployments:
		if slice not in slice_deploy_lookup or \
		   expected_deployment not in slice_deploy_lookup[slice]:
			sd = SliceDeployment(slice=slice, deployment=expected_deployment)
			sd.save()

	# make sure slice has at least 1 public and 1 private networkd
	public_nets = []
	private_net = None
	networks = Network.objects.filter(owner=slice)
	for network in networks:
		if network.template.name == 'Public dedicated IPv4':
			public_nets.append(network)
		elif network.template.name == 'Public shared IPv4':
			public_nets.append(network)
		elif network.template.name == 'Private':
			private_net = network
	if not public_nets:
                # ensure there is at least one public network, and default it to dedicated
		dedicated_public_net = Network(
          	    name = slice.name+'-public',
             	    template = NetworkTemplate.objects.get(name='Public dedicated IPv4'),
          	    owner = slice
      		    )
		dedicated_public_net.save()
                public_nets.append(dedicated_public_net)

	if not private_net:
        	private_net = Network(
          	name = slice.name+'-private',
          	template = NetworkTemplate.objects.get(name='Private'),
          	owner = slice
      		)
      		private_net.save()
	# create slice networks
	public_net_slice = None
	private_net_slice = None
	net_slices = NetworkSlice.objects.filter(slice=slice, network__in=[private_net]+public_nets)
	for net_slice in net_slices:
		if net_slice.network in public_nets:
			public_net_slice = net_slice
		elif net_slice.network == private_net:
			private_net_slice = net_slice
	if not public_net_slice:
		public_net_slice = NetworkSlice(slice=slice, network=public_nets[0])
		public_net_slice.save()
	if not private_net_slice:
		private_net_slice = NetworkSlice(slice=slice, network=private_net)
		private_net_slice.save()




