import os
import base64
from collections import defaultdict
from django.db.models import F, Q
from xos.config import Config
from synchronizers.base.syncstep import *
from core.models import Controller
from core.models import Image, ControllerImages
from xos.logger import observer_logger as logger
from synchronizers.base.ansible import *
from services.vrouter.models import VRouterTenant
from services.onos.models import ONOSService
from services.fabric.models import FabricService
import json

class SyncVRouterTenant(SyncStep):
    provides=[VRouterTenant]
    observes = VRouterTenant
    requested_interval=30
    playbook='sync_host.yaml'

    def get_fabric_onos_service(self):
        fos = None
        fs = FabricService.get_service_objects().all()[0]
        if fs.subscribed_tenants.exists():
            app = fs.subscribed_tenants.all()[0]
            if app.provider_service:
                ps = app.provider_service
                fos = ONOSService.get_service_objects().filter(id=ps.id)[0]
        return fos

    def get_node_tag(self, node, tagname):
        tags = Tag.select_by_content_object(node).filter(name=tagname)
        return tags[0].value

    def fetch_pending(self, deleted):
        fs = FabricService.get_service_objects().all()[0]
        if not fs.autoconfig:
            return None

        if (not deleted):
            objs = VRouterTenant.get_tenant_objects().filter(Q(lazy_blocked=False))
        else:
            objs = VRouterTenant.get_deleted_tenant_objects()

        # Check that each is a valid vCPE tenant or instance
        for vroutertenant in objs:
            # Do we have a vCPE subscriber_tenant?
            if vroutertenant.subscriber_tenant:
                sub = vroutertenant.subscriber_tenant
                if sub.kind != 'vCPE' or not sub.get_attribute("instance_id"):
                    objs.remove(vroutertenant)
            else:
                # Maybe the VRouterTenant is for an instance
                instance_id = vroutertenant.get_attribute("tenant_for_instance_id")
                if not instance_id:
                    objs.remove(vroutertenant)
                else:
                    instance = Instance.objects.filter(id=instance_id)[0]
                    if not instance.instance_name:
                        objs.remove(vroutertenant)

        return objs

    def map_sync_inputs(self, vroutertenant):

        fos = self.get_fabric_onos_service()

        name = None
        instance = None
        # VRouterTenant setup is kind of hacky right now, we'll
        # need to revisit.  The idea is:
        # * Look up the instance corresponding to the address
        # * Look up the node running the instance
        # * Get the "location" tag, push to the fabric
        if vroutertenant.subscriber_tenant:
            sub = vroutertenant.subscriber_tenant
            instance_id = sub.get_attribute("instance_id")
            instance = Instance.objects.filter(id=instance_id)[0]
            name = str(sub)
        else:
            instance_id = vroutertenant.get_attribute("tenant_for_instance_id")
            instance = Instance.objects.filter(id=instance_id)[0]
            name = str(instance)

        node = instance.node
        location = self.get_node_tag(node, "location")

        # Create JSON
        data = {
            "%s/-1" % vroutertenant.public_mac : {
                "basic" : {
                    "ips" : [ vroutertenant.public_ip ],
                    "location" : location
                }
            }
        }
        # Stupid Ansible... leading space so it doesn't think it's a dict
        rest_body = " " + json.dumps(data)

        # Is it a POST or DELETE?

        fields = {
            'rest_hostname': fos.rest_hostname,
            'rest_port': fos.rest_port,
            'rest_endpoint': "onos/v1/network/configuration/hosts",
            'rest_body': rest_body,
            'ansible_tag': '%s'%name, # name of ansible playbook
        }
        return fields

    def map_sync_outputs(self, controller_image, res):
        pass
