import os
import base64
import string
import sys
import socket
from sets import Set
if __name__ == '__main__':
    sys.path.append("/opt/planetstack")
    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")

