from view_common import *
from core.models import *
import functools
from django.contrib.auth.models import BaseUserManager
from django.core import serializers
from django.core.mail import EmailMultiAlternatives

BLESSED_DEPLOYMENTS = ["US-MaxPlanck", "US-GeorgiaTech", "US-Princeton", "US-Washington", "US-Stanford"]

class RequestAccessView(View):
    def post(self, request, *args, **kwargs):
	email = request.POST.get("email", "0")
	firstname = request.POST.get("firstname", "0")
	lastname = request.POST.get("lastname", "0")
	site = request.POST.get("site","0")
	user = User(
            email=BaseUserManager.normalize_email(email),
            firstname=firstname,
            lastname=lastname,
	    is_active=False
        )
        user.save()
	user.site=Site.objects.get(name=site)
	user.save(update_fields=['site'])
	sitePriv = SitePrivilege.objects.filter(site=user.site)
	userId = user.id
	userUrl = "http://"+request.get_host()+"/admin/core/user/"+str(userId)
	for sp in sitePriv:
		subject, from_email, to = 'Authorize OpenCloud User Account', 'support@opencloud.us', str(sp.user)
		text_content = 'This is an important message.'
		html_content = """<p>Please authorize the following user on site """+site+""": <br><br>User: """+firstname+""" """+lastname+"""<br>Email: """+email+"""<br><br>
Check the checkbox next to Is Active property at <a href="""+userUrl+"""> this link</a> to authorize the user. If you do not recognize this individual, or otherwise do not want to approve this account, please ignore this email. If you do not approve this request in 48 hours, the account will automatically be deleted.</p>"""
		msg = EmailMultiAlternatives(subject,text_content, from_email, [to])
		msg.attach_alternative(html_content, "text/html")
		msg.send()
        return HttpResponse(serializers.serialize("json",[user,]), content_type='application/javascript')

class TenantCreateSlice(View):
    def post(self, request, *args, **kwargs):
        if request.user.isReadOnlyUser():
            return HttpResponseForbidden("User is in read-only mode")

        sliceName = request.POST.get("sliceName", "0")
        serviceClass = request.POST.get("serviceClass", "0")
        imageName = request.POST.get("imageName", "0")
        actionToDo = request.POST.get("actionToDo", "0")
        networkPorts = request.POST.get("network","0")
        mountDataSets = request.POST.get("mountDataSets","0")
        privateVolume = request.POST.get("privateVolume","0")
        userEmail = request.POST.get("userEmail","0")
        if (actionToDo == "add"):
           serviceClass = ServiceClass.objects.get(name=serviceClass)
           site = request.user.site
           image = Image.objects.get(name=imageName)
           newSlice = Slice(name=sliceName,serviceClass=serviceClass,site=site,imagePreference=image,mountDataSets=mountDataSets)
           newSlice.save()
	   privateTemplate="Private"
	   publicTemplate="Public shared IPv4"
	   privateNetworkName = sliceName+"-"+privateTemplate
	   publicNetworkName = sliceName+"-"+publicTemplate
	   slice=Slice.objects.get(name=sliceName)
	   addNetwork(privateNetworkName,privateTemplate,slice)
	   addNetwork(publicNetworkName,publicTemplate,slice)
	   addOrModifyPorts(networkPorts,sliceName)
	   if privateVolume=="true":
	   	privateVolForSlice(request.user,sliceName)
	   slicePrivs=SlicePrivilege(user=User.objects.get(email=userEmail),slice=Slice.objects.get(name=sliceName),role=SliceRole.objects.get(role="admin"))
           slicePrivs.save()
        return HttpResponse(json.dumps("Slice created"), content_type='application/javascript')

class TenantAddUser(View):
    def post(self, request, *args, **kwargs):
        if request.user.isReadOnlyUser():
            return HttpResponseForbidden("User is in read-only mode")

        sliceName = request.POST.get("sliceName", "0")
        userEmail = request.POST.get("userEmail","0")
        slicePrivs=SlicePrivilege(user=User.objects.get(email=userEmail),slice=Slice.objects.get(name=sliceName),role=SliceRole.objects.get(role="admin"))
        slicePrivs.save()
        return HttpResponse(json.dumps("Slice created"), content_type='application/javascript')

def privateVolForSlice(user,sliceName):
	if not hasPrivateVolume(sliceName):
	   volumeName=createPrivateVolume(user,sliceName)
	   readWrite="true"
	   mountVolume(sliceName,volumeName,readWrite)

class TenantUpdateSlice(View):
    def post(self, request, *args, **kwargs):
        if request.user.isReadOnlyUser():
            return HttpResponseForbidden("User is in read-only mode")

        sliceName = request.POST.get("sliceName", "0")
        serviceClass = request.POST.get("serviceClass", "0")
        imageName = request.POST.get("imageName", "0")
        actionToDo = request.POST.get("actionToDo", "0")
        networkPorts = request.POST.get("networkPorts","0")
        dataSet = request.POST.get("dataSet","0")
        privateVolume = request.POST.get("privateVolume","0")
        slice = Slice.objects.all()
        for entry in slice:
                serviceClass = ServiceClass.objects.get(name=serviceClass)
                if(entry.name==sliceName):
                         if (actionToDo == "update"):
                                setattr(entry,'serviceClass',serviceClass)
                                setattr(entry,'imagePreference',imageName)
                                setattr(entry,'mountDataSets',dataSet)
                                entry.save()
                                break
	addOrModifyPorts(networkPorts,sliceName)
	if privateVolume=="true":
                privateVolForSlice(request.user,sliceName)
        return HttpResponse(json.dumps("Slice updated"), content_type='application/javascript')

def addNetwork(name,template,sliceName):
	networkTemplate=NetworkTemplate.objects.get(name=template)
	newNetwork = Network(name = name,
                              template = networkTemplate,
                              owner = sliceName)
        newNetwork.save()
	addNetworkSlice(newNetwork,sliceName)

def addNetworkSlice(networkSlice,sliceName):
	newNetworkSlice=NetworkSlice(network =networkSlice,
				     slice=sliceName)
	newNetworkSlice.save()

def addOrModifyPorts(networkPorts,sliceName):
	networkList = Network.objects.all()
        networkInfo = []
        if networkPorts:
           for networkEntry in networkList:
               networkSlices = networkEntry.slices.all()
               for slice in networkSlices:
                   if slice.name==sliceName:
                          if networkEntry.template.name=="Public shared IPv4":
                             setattr(networkEntry,'ports',networkPorts)
                             networkEntry.save()

def getTenantSliceInfo(user, tableFormat = False):
    tenantSliceDetails = {}
    tenantSliceData = getTenantInfo(user)
    tenantServiceClassData = getServiceClassInfo(user)
    if (tableFormat):
       tenantSliceDetails['userSliceInfo'] = userSliceTableFormatter(tenantSliceData)
       tenantSliceDetails['sliceServiceClass']=userSliceTableFormatter(tenantServiceClassData)
    else:
       tenantSliceDetails['userSliceInfo'] = tenantSliceData
    tenantSliceDetails['sliceServiceClass']=userSliceTableFormatter(tenantServiceClassData)
    tenantSliceDetails['image']=userSliceTableFormatter(getImageInfo(user))
    tenantSliceDetails['deploymentSites']=userSliceTableFormatter(getDeploymentSites())
    #tenantSliceDetails['sites'] = userSliceTableFormatter(getTenantSitesInfo())
    tenantSliceDetails['mountDataSets'] = userSliceTableFormatter(getMountDataSets())
    tenantSliceDetails['publicKey'] = getPublicKey(user)
    tenantSliceDetails['availableSites']=userSliceTableFormatter(getAvailableSites())
    tenantSliceDetails['role']=getUserRole(user)
    tenantSliceDetails['siteUsers']=getSiteUsers(user)
    return tenantSliceDetails

def getSiteUsers(user):
	users = User.objects.filter(site=user.site)
	siteUsers=[]
        for entry in users:
		siteUsers.append(str(entry))
	return siteUsers


def getUserRole(user):
	sp=SitePrivilege.objects.filter(user=user)
	for entry in sp:
		return str(entry.role)


def getTenantInfo(user):
    slices =Slice.objects.all()
    userSliceInfo = []
    for entry in slices:
       if (entry.site == user.site):
           sliceName = Slice.objects.get(id=entry.id).name
           slice = Slice.objects.get(name=Slice.objects.get(id=entry.id).name)
           sliceServiceClass = entry.serviceClass.name
           preferredImage =  entry.imagePreference
           #sliceDataSet = entry.mountDataSets
           sliceNetwork = {}
           numSliver = 0
           sliceImage=""
           sliceSite = {}
           sliceNode = {}
           sliceInstance= {}
           #createPrivateVolume(user,sliceName)
           available_sites = getAvailableSites()
           for sliver in slice.slivers.all():
                if sliver.node.site.name in available_sites:
                    sliceSite[sliver.node.site.name] = sliceSite.get(sliver.node.site.name,0) + 1
                    sliceImage = sliver.image.name
                    sliceNode[str(sliver)] = sliver.node.name
           numSliver = sum(sliceSite.values())
           numSites = len(sliceSite)
           userSliceInfo.append({'sliceName': sliceName,'sliceServiceClass': sliceServiceClass,'preferredImage':preferredImage,'numOfSites':numSites, 'sliceSite':sliceSite,'sliceImage':sliceImage,'numOfSlivers':numSliver,'instanceNodePair':sliceNode})
    return userSliceInfo

def getTenantSitesInfo():
        availableSites=getAvailableSites()
	tenantSiteInfo=[]
        for entry in Site.objects.all():
            if entry.name in availableSites:
		 tenantSiteInfo.append({'siteName':entry.name})
	return tenantSiteInfo

def getPublicKey(user):
	users=User.objects.all()
        for key in users:
        	if (str(key.email)==str(user)):
                    	sshKey = key.public_key
        return sshKey

def getServiceClassInfo(user):
    serviceClassList = ServiceClass.objects.all()
    sliceInfo = []
    for entry in serviceClassList:
          sliceInfo.append({'serviceClass':entry.name})
    return sliceInfo

def getImageInfo(user):
    #imageList = Image.objects.all()
    #imageInfo = []
    #for imageEntry in imageList:
          #imageInfo.append({'Image':imageEntry.name})
    imageInfo = []
    tempImageInfo = []
    length = len(BLESSED_DEPLOYMENTS)
    for deployment in Deployment.objects.all():
        if deployment.name in BLESSED_DEPLOYMENTS:
            for x in deployment.imagedeployments_set.all():
                tempImageInfo.append(x.image.name)
    temp = {}
    for i in set(tempImageInfo):
    	temp[i] = tempImageInfo.count(i)
    for key in temp:
	if temp[key]>1:
		imageInfo.append(key)
    return imageInfo

def createPrivateVolume(user, sliceName):
    caps = Volume.CAP_READ_DATA | Volume.CAP_WRITE_DATA | Volume.CAP_HOST_DATA
    getattr(Volume.default_gateway_caps,"read data") | \
           getattr(Volume.default_gateway_caps,"write data") | \
           getattr(Volume.default_gateway_caps,"host files")
    v = Volume(name="private_" + sliceName, owner_id=user, description="private volume for %s" % sliceName, blocksize=61440, private=True, archive=False, default_gateway_caps = caps)
    v.save()
    return v

SYNDICATE_REPLICATE_PORTNUM = 1025

def get_free_port():
    inuse={}
    inuse[SYNDICATE_REPLICATE_PORTNUM] = True
    for vs in VolumeSlice.objects.all():
        inuse[vs.peer_portnum]=True
        inuse[vs.replicate_portnum]=True
    for network in Network.objects.all():
        if not network.ports:
            continue
        network_ports = [x.strip() for x in network.ports.split(",")]
        for network_port in network_ports:
            try:
                inuse[int(network_port)] = True
            except:
                # in case someone has put a malformed port number in the list
                pass
    for i in range(1025, 65535):
        if not inuse.get(i,False):
            return i
    return False

def mountVolume(sliceName, volumeName, readWrite):
    slice = Slice.objects.get(name=sliceName)
    volume = Volume.objects.get(name=volumeName)
    # choose some unused port numbers
    flags = Volume.CAP_READ_DATA
    if readWrite:
        flags = flags | Volume.CAP_WRITE_DATA
    vs = VolumeSlice(volume_id = volume, slice_id = slice, gateway_caps=flags, peer_portnum = get_free_port(), replicate_portnum = SYNDICATE_REPLICATE_PORTNUM)
    vs.save()

def hasPrivateVolume(sliceName):
     slice = Slice.objects.get(name=sliceName)
     for vs in VolumeSlice.objects.filter(slice_id=slice):
         if vs.volume_id.private:
             return True
     return False

def getMountDataSets():
        dataSetInfo=[]
        for volume in Volume.objects.all():
            if not volume.private:
                dataSetInfo.append({'DataSet': volume.name})

        return dataSetInfo

def getDeploymentSites():
    deploymentList = Deployment.objects.all()
    deploymentInfo = []
    for entry in deploymentList:
        deploymentInfo.append({'DeploymentSite':entry.name})
    return deploymentInfo

def getAvailableSites():
    available_sites = []
    for deployment in Deployment.objects.all():
        if deployment.name in BLESSED_DEPLOYMENTS:
            for x in deployment.sitedeployments_set.all():
		if x.site.nodes.all():
                	available_sites.append(x.site.name)
    return list(set(available_sites))

class TenantDeleteSliceView(View):
        def post(self,request):
                if request.user.isReadOnlyUser():
                    return HttpResponseForbidden("User is in read-only mode")
                sliceName = request.POST.get("sliceName",None)
                slice = Slice.objects.get(name=sliceName)
                #print slice, slice.id
                sliceToDel=Slice(name=sliceName, id=slice.id)
                sliceToDel.delete()
                return HttpResponse(json.dumps("Slice deleted"), content_type='application/javascript')

class TenantAddOrRemoveSliverView(View):
    """ Add or remove slivers from a Slice

        Arguments:
            siteName - name of site. If not specified, PlanetStack will pick the
                       best site.,
            actionToDo - [add | rem]
            count - number of slivers to add or remove
            sliceName - name of slice
            noAct - if set, no changes will be made to db, but result will still
                    show which sites would have been modified.

        Returns:
            Dictionary of sites that were modified, and the count of nodes
            that were added or removed at each site.
    """
    def post(self, request, *args, **kwargs):
        siteName = request.POST.get("siteName", None)
        actionToDo = request.POST.get("actionToDo", None)
        count = int(request.POST.get("count","0"))
	sliceName = request.POST.get("slice", None)
	imageName = request.POST.get("image",None)
        noAct = request.POST.get("noAct", False)

        if not sliceName:
            return HttpResponseServerError("No slice name given")

        slice = Slice.objects.get(name=sliceName)
	image = Image.objects.get(name=imageName)

        if siteName:
            siteList = [Site.objects.get(name=siteName)]
        else:
            siteList = None

        if (actionToDo == "add"):
            user_ip = request.GET.get("ip", get_ip(request))
            if (siteList is None):
                siteList = tenant_pick_sites(user, user_ip, slice, count)

            sitesChanged = slice_increase_slivers(request.user, user_ip, siteList, slice, image, count, noAct)
        elif (actionToDo == "rem"):
            sitesChanged = slice_decrease_slivers(request.user, siteList, slice, count, noAct)
        else:
            return HttpResponseServerError("Unknown actionToDo %s" % actionToDo)

        return HttpResponse(json.dumps(sitesChanged), content_type='application/javascript')

    def get(self, request, *args, **kwargs):
        request.POST = request.GET
        return self.post(request, *args, **kwargs)  # for testing REST in browser
        #return HttpResponseServerError("GET is not supported")

class TenantPickSitesView(View):
    """ primarily just for testing purposes """
    def get(self, request, *args, **kwargs):
        count = request.GET.get("count","0")
	slice = request.GET.get("slice",None)
        if slice:
            slice = Slice.objects.get(name=slice)
        ip = request.GET.get("ip", get_ip(request))
        sites = tenant_pick_sites(request.user, user_ip=ip, count=0, slice=slice)
        sites = [x.name for x in sites]
        return HttpResponse(json.dumps(sites), content_type='application/javascript')

def siteSortKey(site, slice=None, count=None, lat=None, lon=None):
    # try to pick a site we're already using
    has_slivers_here=False
    if slice:
        for sliver in slice.slivers.all():
            if sliver.node.site.name == site.name:
                has_slivers_here=True

    # Haversine method
    d = haversine(site.location.latitude, site.location.longitude, lat, lon)

    return (-has_slivers_here, d)

def tenant_pick_sites(user, user_ip=None, slice=None, count=None):
    """ Returns list of sites, sorted from most favorable to least favorable """
    lat=None
    lon=None
    try:
        client_geo = GeoIP().city(user_ip)
        if client_geo:
            lat=float(client_geo["latitude"])
            lon=float(client_geo["longitude"])
    except:
        print "exception in geo code"
        traceback.print_exc()

    available_sites = getAvailableSites()
    sites = Site.objects.all()
    sites = [x for x in sites if x.name in available_sites]
    sites = sorted(sites, key=functools.partial(siteSortKey, slice=slice, count=count, lat=lat, lon=lon))

    return sites

class TenantViewData(View):
    def get(self, request, **kwargs):
        return HttpResponse(json.dumps(getTenantSliceInfo(request.user, True)), content_type='application/javascript')

class RequestAccountView(View):
    def get(self, request, **kwargs):
        return HttpResponse()
