import os
import base64
from django.db.models import F, Q
from planetstack.config import Config
from observer.openstacksyncstep import OpenStackSyncStep
from core.models.network import *

class SyncNetworkSlivers(OpenStackSyncStep):
    requested_interval = 3600
    provides=[NetworkSliver]

    def call(self, failed=[]):
        networkSlivers = NetworkSliver.objects.all()
        networkSlivers_by_id = {}
        networkSlivers_by_port = {}
        for networkSliver in networkSlivers:
            networkSlivers_by_id[networkSliver.id] = networkSliver
            networkSlivers_by_port[networkSliver.port_id] = networkSliver

        networks = Network.objects.all()
        networks_by_id = {}
        for network in networks:
            networks_by_id[network.network_id] = network

        slivers = Sliver.objects.all()
        slivers_by_instance_id = {}
        for sliver in slivers:
            slivers_by_instance_id[sliver.instance_id] = sliver

        ports = self.driver.shell.quantum.list_ports()["ports"]
        for port in ports:
            if port["id"] in networkSlivers_by_port:
                # we already have it
                print "already accounted for port", port["id"]
                continue

            if port["device_owner"] != "compute:nova":
                # we only want the ports that connect to instances
                continue

            network = networks_by_id.get(port['network_id'], None)
            if not network:
                #print "no network for port", port["id"], "network", port["network_id"]
                continue

            sliver = slivers_by_instance_id.get(port['device_id'], None)
            if not sliver:
                print "no sliver for port", port["id"], "device_id", port['device_id']
                continue

            if network.template.sharedNetworkId is not None:
                # If it's a shared network template, then more than one network
                # object maps to the quantum network. We have to do a whole bunch
                # of extra work to find the right one.
                networks = network.template.network_set.all()
                network = None
                for candidate_network in networks:
                    if (candidate_network.owner == sliver.slice):
                        print "found network", candidate_network
                        network = candidate_network

                if not network:
                    print "failed to find the correct network for a shared template for port", port["id"], "network", port["network_id"]
                    continue

            if not port["fixed_ips"]:
                print "port", port["id"], "has no fixed_ips"
                continue

#             print "XXX", port

            ns = NetworkSliver(network=network,
                               sliver=sliver,
                               ip=port["fixed_ips"][0]["ip_address"],
                               port_id=port["id"])
            ns.save()
