from django.test import TestCase
from rest_framework.test import APIRequestFactory, force_authenticate

from rest_framework.reverse import reverse
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError

from .views import *
from .models import *

from uncloud_pay.models import BillingAddress, Order

class VPNTests(TestCase):
    def setUp(self):
        self.user = get_user_model().objects.create_user('django-test-user', 'noreply@ungleich.ch')
        self.admin_user = get_user_model().objects.create_user('django-test-adminuser',
                                                               'noreply-admin@ungleich.ch')



        self.admin_user.is_staff = True
        self.admin_user.save()

        self.pool_network = '2001:db8::'
        self.pool_network2 = '2001:db8:1::'
        self.pool_network_size = '48'
        self.pool_subnetwork_size = '64'
        self.pool_vpn_hostname = 'vpn.example.org'
        self.pool_wireguard_private_key = 'MOz8kk0m4jhNtAXlge0qzexZh1MipIhu4HJwtdvZ2EY='

        self.vpn_wireguard_public_key = 'B2b78eWBIXPMM1x4DDjkCDZepS0qDgcLN3T3PjcgXkY='

        self.vpnpool = VPNPool.objects.get_or_create(network=self.pool_network,
                                                     network_size=self.pool_network_size,
                                                     subnetwork_size=self.pool_subnetwork_size,
                                                     vpn_hostname=self.pool_vpn_hostname,
                                                     wireguard_private_key=self.pool_wireguard_private_key
        )

        self.factory = APIRequestFactory()


    def test_create_vpnpool(self):
        url = reverse("vpnpool-list")
        view = VPNPoolViewSet.as_view({'post': 'create'})
        request = self.factory.post(url, { 'network': self.pool_network2,
                                           'network_size': self.pool_network_size,
                                           'subnetwork_size': self.pool_subnetwork_size,
                                           'vpn_hostname': self.pool_vpn_hostname,
                                           'wireguard_private_key': self.pool_wireguard_private_key

        })
        force_authenticate(request, user=self.admin_user)
        response = view(request)

        # This raises an exception if the request was not successful
        # No assert needed
        pool = VPNPool.objects.get(network=self.pool_network2)

    def test_create_vpn(self):
        url = reverse("vpnnetwork-list")
        view = VPNNetworkViewSet.as_view({'post': 'create'})
        request = self.factory.post(url, { 'network_size': self.pool_subnetwork_size,
                                           'wireguard_public_key': self.vpn_wireguard_public_key

        })
        force_authenticate(request, user=self.user)

        # we don't have a billing address -> should raise an error
        with self.assertRaises(ValidationError):
            response = view(request)

        addr = BillingAddress.objects.get_or_create(
            owner=self.user,
            active=True,
            defaults={'organization': 'ungleich',
                      'name': 'Nico Schottelius',
                      'street': 'Hauptstrasse 14',
                      'city': 'Luchsingen',
                      'postal_code': '8775',
                      'country': 'CH' }
        )

        # This should work now
        response = view(request)

        # Verify that an order was created successfully - there should only be one order at
        # this point in time
        order = Order.objects.get(owner=self.user)


    def tearDown(self):
        self.user.delete()
        self.admin_user.delete()