import os
import json
import socket
import sys
import time
import traceback
import xmlrpclib

#  XXX for testing
#sys.path.append("/opt/planetstack")
#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")

from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

def ps_id_to_pl_id(x):
    # Since we don't want the PlanetStack object IDs to conflict with existing
    # PlanetLab object IDs in the CMI, just add 100000 to the PlanetStack object
    # IDs.
    return 100000 + x

def pl_id_to_ps_id(x):
    return x - 100000

# slice_remap is a dict of ps_slice_name -> (pl_slice_name, pl_slice_id)

def pl_slice_id(slice, slice_remap={}):
    if slice.name in slice_remap:
        return int(slice_remap[slice.name][1])
    else:
        return ps_id_to_pl_id(slice.id)

def pl_slicename(slice, slice_remap={}):
    if slice.name in slice_remap:
        return slice_remap[slice.name][0]
    else:
        return slice.name

def filter_fields(src, fields):
    dest = {}
    for (key,value) in src.items():
        if (not fields) or (key in fields):
            dest[key] = value
    return dest

def GetSlices(filter={}, slice_remap={}):
    #ps_slices = Slice.objects.filter(**filter)
    ps_slices = Slice.objects.all()
    slices = []
    for ps_slice in ps_slices:
        if (filter) and ("name" in filter):
            remapped_name = slice_remap.get(ps_slice.name, (ps_slice.name,))[0]
            if (remapped_name != filter["name"]):
                continue

        node_ids=[]
        for ps_sliver in ps_slice.slivers.all():
            node_ids.append(ps_id_to_pl_id(ps_sliver.node.id))

        slice = {"instantiation": "plc-instantiated",
                 "description": "planetstack slice",
                 "slice_id": pl_slice_id(ps_slice, slice_remap),
                 "node_ids": node_ids,
                 "url": "planetstack",
                 "max_nodes": 1000,
                 "peer_slice_id": None,
                 "slice_tag_ids": [],
                 "peer_id": None,
                 "site_id": ps_id_to_pl_id(ps_slice.site_id),
                 "name": pl_slicename(ps_slice, slice_remap),
                 "planetstack_name": ps_slice.name}

                 # creator_person_id, person_ids, expires, created

        slices.append(slice)
    return slices

def GetNodes(node_ids=None, fields=None, slice_remap={}):
    if node_ids:
        ps_nodes = Node.objects.filter(id__in=[pl_id_to_ps_id(nid) for nid in node_ids])
    else:
        ps_nodes = Node.objects.all()
    nodes = []
    for ps_node in ps_nodes:
        slice_ids=[]
        for ps_sliver in ps_node.slivers.all():
            slice_ids.append(pl_slice_id(ps_sliver.slice, slice_remap))

        node = {"node_id": ps_id_to_pl_id(ps_node.id),
                "site_id": ps_id_to_pl_id(ps_node.site_id),
                "node_type": "regular",
                "peer_node_id": None,
                "hostname": ps_node.name,
                "conf_file_ids": [],
                "slice_ids": slice_ids,
                "model": "planetstack",
                "peer_id": None,
                "node_tag_ids": []}

                # last_updated, key, boot_state, pcu_ids, node_type, session, last_boot,
                # interface_ids, slice_ids_whitelist, run_level, ssh_rsa_key, last_pcu_reboot,
                # nodegroup_ids, verified, last_contact, boot_nonce, version,
                # last_pcu_configuration, last_download, date_created, ports

        nodes.append(node)

    nodes = [filter_fields(node, fields) for node in nodes]

    return nodes

def GetTags(slicename,node_id):
    return {}

def GetSites(slice_remap={}):
    ps_sites = Site.objects.all()
    sites = []
    for ps_site in ps_sites:
        slice_ids=[]
        for ps_slice in ps_site.slices.all():
            slice_ids.append(pl_slice_id(ps_slice, slice_remap))

        node_ids=[]
        for ps_node in ps_site.nodes.all():
            node_ids.append(ps_id_to_pl_id(ps_node.id))

        site = {"site_id": ps_id_to_pl_id(ps_site.id),
                "node_ids": node_ids,
                "pcu_ids": [],
                "max_slices": 100,
                "max_slivers": 1000,
                "is_public": False,
                "peer_site_id": None,
                "abbrebiated_name": ps_site.abbreviated_name,
                "address_ids": [],
                "name": ps_site.name,
                "url": None,
                "site_tag_ids": [],
                "enabled": True,
                "longitude": float(ps_site.location.longitude),
                "latitude": float(ps_site.location.latitude),
                "slice_ids": slice_ids,
                "login_base": ps_site.login_base,
                "peer_id": None}

                # last_updated, ext_consortium_id, person_ids, date_created

        sites.append(site)

    return sites

def GetInterfaces(slicename, node_ids):
    interfaces = []
    ps_slices = Slice.objects.filter(name=slicename)
    for ps_slice in ps_slices:
        for ps_sliver in ps_slice.slivers.all():
            node_id = ps_id_to_pl_id(ps_sliver.node_id)
            if node_id in node_ids:
                ps_node = ps_sliver.node
                interface = {"node_id": node_id,
                             "ip": socket.gethostbyname(ps_node.name),
                             "broadcast": None,
                             "mac": "11:22:33:44:55:66",
                             "bwlimit": None,
                             "network": None,
                             "is_primary": True,
                             "dns1": None,
                             "hostname": None,
                             "netmask": None,
                             "interface_tag_ids": [],
                             "interface_id": node_id,     # assume each node has only one interface
                             "gateway": None,
                             "dns2": None,
                             "type": "ipv4",
                             "method": "dhcp"}
                interfaces.append(interface)
    return interfaces

def GetConfiguration(name, slice_remap={}):
    slicename = name["name"]
    if "node_id" in name:
        node_id = name["node_id"]
    else:
        node_id = 0

    node_sliver_tags = GetTags(slicename, node_id)

    slices = GetSlices({"name": slicename}, slice_remap=slice_remap)
    perhost = {}
    allinterfaces = {}
    hostipmap = {}
    nodes = []
    if len(slices)==1:
        slice = slices[0]
        node_ids = slice['node_ids']
        nodes = GetNodes(node_ids, ['hostname', 'node_id', 'site_id'], slice_remap=slice_remap)
        nodemap = {}
        for node in nodes:
            nodemap[node['node_id']]=node['hostname']

        interfaces = GetInterfaces(slice["planetstack_name"], node_ids)
        print "XXX", interfaces
        hostipmap = {}
        for interface in interfaces:
            if nodemap[interface['node_id']] not in allinterfaces:
                allinterfaces[nodemap[interface['node_id']]] = []
            interface['interface_tags'] = []
            allinterfaces[nodemap[interface['node_id']]].append(interface)
            if interface['is_primary']:
                hostipmap[nodemap[interface['node_id']]] = interface['ip']

        for nid in node_ids:
            sliver_tags = GetTags(slicename,nid)
            perhost[nodemap[nid]] = sliver_tags

    slivers = GetSlices(slice_remap=slice_remap)
    if node_id != 0:
        slivers = [slice for slice in slivers if (node_id in slice.node_ids)]

    sites = GetSites(slice_remap=slice_remap)
    for site in sites:
        site["site_tags"] = []

    timestamp = int(time.time())
    return {'version': 3,
            'timestamp': timestamp,
            'configuration': node_sliver_tags,
            'allconfigurations':perhost,
            'hostipmap':hostipmap,
            'slivers': slivers,
            'interfaces': allinterfaces,
            'sites': sites,
            'nodes': nodes}

DEFAULT_REMAP = {"princeton_vcoblitz2": ["princeton_vcoblitz", 70]}

def HandleGetConfiguration1():
    configs={}
    for slicename in ["princeton_vcoblitz"]:
        configs[slicename] = GetConfiguration({"name": slicename}, DEFAULT_REMAP)
    return configs

def HandleGetNodes1():
    return GetNodes(slice_remap=DEFAULT_REMAP)

def HandleGetSlices1():
    return GetSlices(slice_remap=DEFAULT_REMAP)

def HandleGetConfiguration2(name, slice_remap):
    return GetConfiguration(name, slice_remap=slice_remap)

def HandleGetNodes2(slice_remap):
    return GetNodes(slice_remap=slice_remap)

def HandleGetSlices2(slice_remap):
    return GetSlices(slice_remap=slice_remap)

FUNCS = {"GetConfiguration": HandleGetConfiguration1,
         "GetNodes": HandleGetNodes1,
         "GetSlices": HandleGetSlices1,
         "GetConfiguration2": HandleGetConfiguration2,
         "GetNodes2": HandleGetNodes2,
         "GetSlices2": HandleGetSlices2}

@csrf_exempt
def LegacyXMLRPC(request):
    if request.method == "POST":
        try:
            (args, method) = xmlrpclib.loads(request.body)
            result = None
            if method in FUNCS:
                result = FUNCS[method](*args)
            return HttpResponse(xmlrpclib.dumps((result,), methodresponse=True, allow_none=1))
        except:
            traceback.print_exc()
            return HttpResponseServerError()
    else:
        return HttpResponse("Not Implemented")

if __name__ == '__main__':
    slices = GetSlices(slice_remap = DEFAULT_REMAP)
    nodes = GetNodes(slice_remap = DEFAULT_REMAP)

    if ("-d" in sys.argv):
        config = GetConfiguration({"name": "princeton_vcoblitz"}, slice_remap = DEFAULT_REMAP)
        print config
        print slices
        print nodes
    else:
        configs={}
        configs[slicename] = GetConfiguration({"name": "princeton_vcoblitz"})

        file("planetstack_config","w").write(json.dumps(configs))
        file("planetstack_slices","w").write(json.dumps(slices))
        file("planetstack_nodes","w").write(json.dumps(nodes))
