import os
import sys
from django.db.models import Q, F
from services.passivetest.models import PassiveTestService, PassiveTestTenant
from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
from core.models import ModelLink, CoarseTenant, ServiceMonitoringAgentInfo
from xos.logger import Logger, logging
from urlparse import urlparse

parentdir = os.path.join(os.path.dirname(__file__), "..")
sys.path.insert(0, parentdir)

logger = Logger(level=logging.INFO)

class SyncPassiveTestTenant(SyncInstanceUsingAnsible):
    provides = [PassiveTestTenant]
    observes = PassiveTestTenant
    requested_interval = 0
    template_name = "passivetesttenant_playbook.yaml"
    service_key_name = "/opt/xos/synchronizers/passivetest/passivetest_private_key"
    watches = [ModelLink(CoarseTenant,via='coarsetenant'), 
               ModelLink(ServiceMonitoringAgentInfo,via='monitoringagentinfo')]

    def __init__(self, *args, **kwargs):
        super(SyncPassiveTestTenant, self).__init__(*args, **kwargs)

    def fetch_pending(self, deleted):

        if (not deleted):
            objs = PassiveTestTenant.get_tenant_objects().filter(
                Q(enacted__lt=F('updated')) | Q(enacted=None), Q(lazy_blocked=False))
        else:
            # If this is a deletion we get all of the deleted tenants..
            objs = PassiveTestTenant.get_deleted_tenant_objects()

        return objs

    def get_passivetestservice(self, o):
        if not o.provider_service:
            return None

        passivetestservice = PassiveTestService.get_service_objects().filter(id=o.provider_service.id)

        if not passivetestservice:
            return None

        return passivetestservice[0]

    # Gets the attributes that are used by the Ansible template but are not
    # part of the set of default attributes.
    def get_extra_attributes(self, o):
        passivetestservice = self.get_passivetestservice(o)
        return { "public_ip": o.public_ip,
                 "synchronizer_ip": o.synchronizer_ip,
                 "tap_ports": passivetestservice.tap_ports,
                 "reset_viv": passivetestservice.reset_viv}

    def handle_service_monitoringagentinfo_watch_notification(self, monitoring_agent_info):
        if not monitoring_agent_info.service:
            logger.info("handle watch notifications for service monitoring agent info...ignoring because service attribute in monitoring agent info:%s is null" % (monitoring_agent_info))
            return

        if not monitoring_agent_info.target_uri:
            logger.info("handle watch notifications for service monitoring agent info...ignoring because target_uri attribute in monitoring agent info:%s is null" % (monitoring_agent_info))
            return

        objs = PassiveTestTenant.get_tenant_objects().all()
        for obj in objs:
            if obj.provider_service.id != monitoring_agent_info.service.id:
                logger.info("handle watch notifications for service monitoring agent info...ignoring because service attribute in monitoring agent info:%s is not matching" % (monitoring_agent_info))
                return

            instance = self.get_instance(obj)
            if not instance:
               logger.warn("handle watch notifications for service monitoring agent info...: No valid instance found for object %s" % (str(obj)))
               return

            logger.info("handling watch notification for monitoring agent info:%s for PassiveTestTenant object:%s" % (monitoring_agent_info, obj))

            #Run ansible playbook to update the routing table entries in the instance
            fields = self.get_ansible_fields(instance)
            fields["ansible_tag"] =  obj.__class__.__name__ + "_" + str(obj.id) + "_service_monitoring"
            
            #Parse the monitoring agent target_uri
            url = urlparse(monitoring_agent_info.target_uri)

            #Assuming target_uri is rabbitmq URI
            fields["rabbit_user"] = url.username
            fields["rabbit_password"] = url.password
            fields["rabbit_host"] = url.hostname

            template_name = "sync_monitoring_agent.yaml"
            super(SyncPassiveTestTenant, self).run_playbook(obj, fields, template_name)
        pass

