from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework import serializers
from rest_framework import generics
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.views import APIView
from rest_framework import status
from core.models import *
from services.vtn.models import VTNService
from services.vtn.vtnnetport import VTNNetwork, VTNPort
from django.forms import widgets
from django.conf.urls import patterns, url
from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
from django.shortcuts import get_object_or_404
from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
from xos.exceptions import *
import json
import subprocess

class VTNServiceSerializer(PlusModelSerializer):
    id = ReadOnlyField()

    privateGatewayMac = serializers.CharField(required=False)
    localManagementIp = serializers.CharField(required=False)
    ovsdbPort = serializers.IntegerField(required=False)
    sshPort = serializers.IntegerField(required=False)
    sshUser = serializers.CharField(required=False)
    sshKeyFile = serializers.CharField(required=False)
    mgmtSubnetBits = serializers.IntegerField(required=False)
    xosEndpoint = serializers.CharField(required=False)
    xosUser = serializers.CharField(required=False)
    xosPassword = serializers.CharField(required=False)

    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
    class Meta:
        model = VTNService
        fields = ('humanReadableName', 'id', 'privateGatewayMac', 'localManagementIp', 'ovsdbPort', 'sshPort', 'sshUser', 'sshKeyFile',
                  'mgmtSubnetBits', 'xosEndpoint', 'xosUser', 'xosPassword')

    def getHumanReadableName(self, obj):
        return obj.__unicode__()

class VTNNetworkSerializer(serializers.Serializer):
    id = ReadOnlyField()
    name = serializers.CharField(required=False)
    subnet = serializers.CharField(required=False)
    gateway = serializers.CharField(required=False)
    segmentation_id = serializers.CharField(required=False)

    class Meta:
        fields = ('id', 'name', 'subnet', 'gateway', 'segmentation_id')

class VTNServiceNetworkSerializer(serializers.Serializer):
    id = ReadOnlyField()
    type = serializers.CharField(required=False)
    subscriberNetworks = serializers.SerializerMethodField("getSubscriberNetworks")
    providerNetworks = serializers.SerializerMethodField("getProviderNetworks")
    ownerSliceName = ReadOnlyField()
    ownerServiceName = ReadOnlyField()

    class Meta:
        fields = ('id', 'type', "subscriberNetworks", "providerNetworks", "ownerSliceName", "ownerServiceName")

    def getSubscriberNetworks(self, obj):
         return obj.subscriberNetworks

    def getProviderNetworks(self, obj):
         return obj.providerNetworks

class VTNPortSerializer(serializers.Serializer):
    id = ReadOnlyField()
    name = serializers.CharField(required=False)
    network_id = serializers.CharField(required=False)
    network_name = serializers.CharField(required=False)
    mac_address = serializers.CharField(required=False)
    ip_address = serializers.CharField(required=False)

    class Meta:
        fields = ('id', 'name', 'network_id', 'network_name', 'mac_address', 'ip_address')

class FloatingAddressPairSerializer(serializers.Serializer):
    ip_address = ReadOnlyField()
    mac_address = ReadOnlyField()

class VTNServicePortSerializer(serializers.Serializer):
    id = ReadOnlyField()
    vlan_id = serializers.IntegerField(required=False)
    network_name = serializers.CharField(required=False)

    # TODO: structure this better
    floating_address_pairs = serializers.SerializerMethodField("getFloatingAddressPairs")

    class Meta:
        fields = ('id', 'vlan_id', 'network_name')

    def getFloatingAddressPairs(self, obj):
         return obj.floating_address_pairs

class VTNViewSet(XOSViewSet):
    base_name = "vtn"
    method_name = "vtn"
    method_kind = "viewset"

    # these are just because ViewSet needs some queryset and model, even if we don't use the
    # default endpoints
    queryset = VTNService.objects.all()
    model = VTNService
    serializer_class = VTNServiceSerializer

    custom_serializers = {"get_port": VTNPortSerializer,
                          "get_ports": VTNPortSerializer,
                          "get_network": VTNNetworkSerializer,
                          "get_networks": VTNNetworkSerializer}

    @classmethod
    def get_urlpatterns(self, api_path="^"):
        patterns = []

        patterns.append( self.detail_url("services/$", {"get": "get_services"}, "services") )
        patterns.append( self.detail_url("services_names/$", {"get": "get_services_names"}, "services") )
        patterns.append( self.detail_url("services/(?P<service>[a-zA-Z0-9\-_]+)/$", {"get": "get_service"}, "get_service") )

        # Not as RESTful as it could be, but maintain these endpoints for compability
        patterns.append( self.list_url("services/$", {"get": "get_services"}, "rootvtn_services") )
        patterns.append( self.list_url("services_names/$", {"get": "get_services_names"}, "rootvtn_services") )
        patterns.append( self.list_url("services/(?P<service>[a-zA-Z0-9\-_]+)/$", {"get": "get_service"}, "rootvtn_get_service") )

        # Neutron-replacement APIs
        patterns.append( self.list_url("ports/$", {"get": "get_ports"}, "vtn_ports") )
        patterns.append( self.list_url("ports/(?P<port_id>[a-zA-Z0-9\-_]+)/$", {"get": "get_port"}, "vtn_port") )
        patterns.append( self.list_url("networks/$", {"get": "get_networks"}, "vtn_networks") )
        patterns.append( self.list_url("networks/(?P<network_id>[a-zA-Z0-9\-_]+)/$", {"get": "get_network"}, "vtn_network") )

        patterns.append( self.list_url("servicePorts/$", {"get": "get_service_ports"}, "vtn_service_ports") )
        patterns.append( self.list_url("servicePorts/(?P<port_id>[a-zA-Z0-9\-_]+)/$", {"get": "get_service_port"}, "vtn_service_port") )
        patterns.append( self.list_url("serviceNetworks/$", {"get": "get_service_networks"}, "vtn_service_networks") )
        patterns.append( self.list_url("serviceNetworks/(?P<network_id>[a-zA-Z0-9\-_]+)/$", {"get": "get_service_network"}, "vtn_service_network") )

        patterns = patterns + super(VTNViewSet,self).get_urlpatterns(api_path)

        return patterns

    def get_services_names(self, request, pk=None):
        result = {}
        for service in Service.objects.all():
           for id in service.get_vtn_src_names():
               dependencies = service.get_vtn_dependencies_names()
               if dependencies:
                   result[id] = dependencies
        return Response(result)

    def get_services(self, request, pk=None):
        result = {}
        for service in Service.objects.all():
           for id in service.get_vtn_src_ids():
               dependencies = service.get_vtn_dependencies_ids()
               if dependencies:
                   result[id] = dependencies
        return Response(result)

    def get_service(self, request, pk=None, service=None):
        for xos_service in Service.objects.all():
            if service in xos_service.get_vtn_src_ids():
                return Response(xos_service.get_vtn_dependencies_ids())
        return Response([])

    def get_ports(self, request):
        result=[]
        for port in Port.objects.all():
            result.append(VTNPortSerializer(VTNPort(port)).data)
        return Response({"ports": result})

    def get_port(self, request, port_id=None):
        port = Port.objects.filter(port_id = port_id)
        if port:
            port=port[0]
        else:
            return Response("Failed to find port %s" % port_id, status=status.HTTP_404_NOT_FOUND)
        return Response({"port": VTNPortSerializer(VTNPort(port)).data})

    def get_service_ports(self, request):
        result=[]
        for port in Port.objects.all():
            result.append(VTNServicePortSerializer(VTNPort(port)).data)
        return Response({"servicePorts": result})

    def get_service_port(self, request, port_id=None):
        port = Port.objects.filter(port_id = port_id)
        if port:
            port=port[0]
        else:
            return Response("Failed to find port %s" % port_id, status=status.HTTP_404_NOT_FOUND)
        return Response({"servicePort": VTNServicePortSerializer(VTNPort(port)).data})

    def get_networks(self, request):
        result=[]
        for network in Network.objects.all():
            network = VTNNetwork(network)
            if network.id is not None:
                result.append(VTNNetworkSerializer(network).data)
        return Response({"networks": result})

    def get_network(self, request, network_id=None):
        network = [x for x in Network.objects.all() if VTNNetwork(x).id == network_id]
        if network:
            network=network[0]
        else:
            return Response("Failed to find network %s" % network_id, status=status.HTTP_404_NOT_FOUND)
        return Response({"network": VTNNetworkSerializer(VTNNetwork(network)).data})

    def get_service_networks(self, request):
        result=[]
        for network in Network.objects.all():
            network = VTNNetwork(network)
            if network.id is not None:
                result.append(VTNServiceNetworkSerializer(network).data)
        return Response({"serviceNetworks": result})

    def get_service_network(self, request, network_id=None):
        network = [x for x in Network.objects.all() if VTNNetwork(x).id == network_id]
        if network:
            network=network[0]
        else:
            return Response("Failed to find network %s" % network_id, status=status.HTTP_404_NOT_FOUND)
        return Response({"serviceNetwork": VTNServiceNetworkSerializer(VTNNetwork(network)).data})



