import os
import base64
import string
import sys
import socket
from sets import Set
if __name__ == '__main__':
    sys.path.append("/opt/xos")
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")

from planetstack.config import Config
from core.models import Service
from requestrouter.models import RequestRouterService, ServiceMap
from util.logger import Logger, logging
import rrlib_config

logger = Logger(level=logging.INFO)

'''
Conventions:
1) All dnsredir backend will listen at port 9000+ servicemap.pk ( where pk is the primary key generated in django model)
'''

class RequestRouterLibrary:

    def __init__(self):
        pass
    
    def gen_slice_info(self, service=None):   
        """generates sliver information from slice of request router
        """

        if (service is None ):
            service = RequestRouterService.objects.get()

        mapping = {}
        #static mapping for demo purpose 
        #mapping["node47.princeton.vicci.org"] = "128.112.171.112"
        mapping["node48.princeton.vicci.org"] = "128.112.171.114"
    
        '''for slice in service.service.all():
            name = slice.name
            for sliver in slice.slivers.all():
                mapping[sliver.name] = str(sliver.ip)
        '''
        return mapping

    def gen_servicemap_slice_info(self, servicemap):
        """generates sliver information from slice of servicemap
        """

        wzone = Set(['arizona', 'stanford', 'on.lab', 'housten']) # zone=1 in cooden.conf
        ezone = Set(['princeton', 'atlanta', 'new york', 'georgia tech']) # zone=2 in coodeen.conf

        mapping_zone = {}
        mapping_ip = {}
        slice = servicemap.slice
        name = slice.name
        for sliver in slice.slivers.all():
            mapping_ip[sliver.node.name] = socket.gethostbyname(sliver.node.name)
            #print "sliver name "+sliver.name+str(sliver.ip)+"\n"
            site = sliver.node.site.name
            if(site.lower() in wzone):
                mapping_zone[sliver.node.name] = str(1)
            else:
                mapping_zone[sliver.node.name] = str(2)

        return mapping_ip, mapping_zone



    def gen_slice_file(self, service):
        """ generates host file for the slice information
            to be used by ansible to push configuration files
        """

        mapping = self.gen_slice_info(service)

        fn = "/etc/ansible/requestrouter/dnsredir/hosts"
        f = open(fn, "w")
        for (k,v) in mapping.items():
            f.write("%s\n" % k)

        fn = "/etc/ansible/requestrouter/dnsdemux/hosts"
        f = open(fn, "w")
        for (k,v) in mapping.items():
            f.write("%s\n" % k)


    def get_servicemap_uid(self, servicemap):
        seq = ("service_", str(servicemap.pk));
        return "".join(seq)

    def get_service_port(self, servicemap):
                return str(9000+servicemap.pk)

    def gen_dnsredir_serviceconf(self, servicemap):
        objname = self.get_servicemap_uid(servicemap)
    
        rr_mapping = self.gen_slice_info(None)
    
        #generate dnsredir.conf file parameters to be used in static file.
        mapping = {}
        mapping["port_listen"] = self.get_service_port(servicemap)
        mapping["configdir"] = rrlib_config.DNSREDIR_CONFIGDIR_PREFIX+objname+".d/"
        mapping["logdir"] = rrlib_config.DNSREDIR_LOGDIR_PREFIX+objname+".d"
        mapping["pidfile"] = rrlib_config.DNSREDIR_PIDFILE_PREFIX+objname+".pid"
        mapping["domain_name"] = servicemap.prefix      
        mapping["heartbeat_port"] = rrlib_config.HEARTBEAT_PORT

        #generate dnsredir.conf file 

        fn = "./temp_config/dnsredir/"+objname+".conf"
        f = open(fn, "w")
        for (k,v) in rr_mapping.items():
                        f.write(mapping["domain_name"]+". NS "+k+". "+v+" 3600 \n" % mapping)


        f.write("""
Default_TTL 30

Port %(port_listen)s

ConfigDir %(configdir)s

MapsDir maps.d

HTTPPort %(heartbeat_port)d

PidFile %(pidfile)s

HttpRequestPort 8081

""" % mapping)

        #generate configdirectory
        
        os.mkdir("./temp_config/dnsredir/"+objname+".d")
        
        #geenrate codeen_nodes.conf
        mapping_ip, mapping_zone = self.gen_servicemap_slice_info(servicemap)

        codeen_name = "./temp_config/dnsredir/"+objname+".d/codeen_nodes.conf"
        f = open(codeen_name, "w")
        for (k,v) in mapping_zone.items():
            f.write(k+" zone="+v+" \n")

        iptxt = "./temp_config/dnsredir/"+objname+".d/node-to-ip.txt"
        f = open(iptxt, "w")
        for (k,v) in mapping_ip.items():
            f.write(k+" "+v+" \n")

        #generate maps directory
        os.mkdir("./temp_config/dnsredir/"+objname+".d/maps.d")

        # redirection map
        map = "./temp_config/dnsredir/"+objname+".d/maps.d/map.conf"
        f = open(map, "w")
		#hardcoded probable public IP masks from arizona and princeton region respectively
        f.write("prefix "+servicemap.prefix+" \n")
        f.write("map 150.135.211.252/32 zone 1 || zone 2 \n")
        f.write("map 128.112.171.112/24 zone 2 || zone 1 \n")
        f.write("map 0.0.0.0/0 zone 1 || zone 2 \n")


    def gen_dnsdemux_serviceconf(self, servicemap):
        '''
        generates frontend service*.conf file for each of the service
        It assumes that there is a dnsdemux frontend running on the RR istallation and will
        just add a conf file for each service in /etc/dnsdemux/default
        '''
        objname = self.get_servicemap_uid(servicemap)
        #generate dnsdemux.conf file parameters to be used in static file.
       
        port_listen = self.get_service_port(servicemap)
        domain_name = servicemap.prefix  
        #generate service specific .conf file

        rr_mapping = self.gen_slice_info(None)

        fn = "./temp_config/dnsdemux/"+objname+".conf"
        f = open(fn, "w")

        for (k,v) in rr_mapping.items():
            f.write("Forward "+v+" "+port_listen+" 8081 "+domain_name+".\n")

    
    def teardown_temp_configfiles(self, objname):
        if os.path.exists("./temp_config/dnsdemux/"+objname+".conf"):
            os.remove("./temp_config/dnsdemux/"+objname+".conf")
        if os.path.exists("./temp_config/dnsredir/"+objname+".d/maps.d/map.conf"):
            os.remove("./temp_config/dnsredir/"+objname+".d/maps.d/map.conf")
        if os.path.exists("./temp_config/dnsredir/"+objname+".d/maps.d"):
            os.rmdir("./temp_config/dnsredir/"+objname+".d/maps.d")
        if os.path.exists("./temp_config/dnsredir/"+objname+".d/node-to-ip.txt"):
            os.remove("./temp_config/dnsredir/"+objname+".d/node-to-ip.txt")
        if os.path.exists("./temp_config/dnsredir/"+objname+".d/codeen_nodes.conf"):
            os.remove("./temp_config/dnsredir/"+objname+".d/codeen_nodes.conf")
        if os.path.exists("./temp_config/dnsredir/"+objname+".d"):
            os.rmdir("./temp_config/dnsredir/"+objname+".d")
        if os.path.exists("./temp_config/dnsredir/"+objname+".conf"):
            os.remove("./temp_config/dnsredir/"+objname+".conf")

