# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.test import TestCase

from coin.offers.models import Offer, OfferSubscription
from coin.resources.models import IPPool, IPSubnet
from coin.members.models import Member
from coin.members.tests import MemberTestsUtils

from .models import VPNConfiguration


class VPNTestCase(TestCase):
    fixtures = ['example_pools.json', 'offers.json']

    def setUp(self):
        self.v6_pool = IPPool.objects.get(default_subnetsize=56)
        self.v4_pool = IPPool.objects.get(default_subnetsize=32)
        self.offer = Offer.objects.filter(configuration_type="VPNConfiguration")[0]

        # Create a member.
        cn = MemberTestsUtils.get_random_username()
        self.member = Member.objects.create(first_name=u"Toto",
                                            last_name=u"L'artichaut",
                                            username=cn)

        # Create a new VPN with subnets.
        # We need Django to call clean() so that magic happens.
        abo = OfferSubscription(offer=self.offer, member=self.member)
        abo.full_clean()
        abo.save()
        vpn = VPNConfiguration(offersubscription=abo)
        vpn.full_clean()
        vpn.save()
        v6 = IPSubnet(ip_pool=self.v6_pool, configuration=vpn)
        v6.full_clean()
        v6.save()
        v4 = IPSubnet(ip_pool=self.v4_pool, configuration=vpn)
        v4.full_clean()
        v4.save()

        # Create additional VPN, they should automatically be attributed a
        # new login.
        for i in range(5):
            abo = OfferSubscription(offer=self.offer, member=self.member)
            abo.full_clean()
            abo.save()
            vpn = VPNConfiguration(offersubscription=abo)
            vpn.full_clean()
            vpn.save()

    def tearDown(self):
        """Properly clean up objects, so that they don't stay in LDAP"""
        for vpn in VPNConfiguration.objects.all():
            vpn.delete()
        Member.objects.get().delete()

    def test_has_ipv4_endpoint(self):
        vpn = VPNConfiguration.objects.all()[0]
        self.assertIsNotNone(vpn.ipv4_endpoint)

    def test_has_correct_ipv4_endpoint(self):
        """If there is not endpoint, we consider it to be correct."""
        vpn = VPNConfiguration.objects.all()[0]
        if vpn.ipv4_endpoint is not None:
            subnet = vpn.ip_subnet.get(ip_pool=self.v4_pool)
            self.assertIn(vpn.ipv4_endpoint, subnet.inet)

    def test_has_ipv6_endpoint(self):
        vpn = VPNConfiguration.objects.all()[0]
        self.assertIsNotNone(vpn.ipv6_endpoint)

    def test_has_correct_ipv6_endpoint(self):
        """If there is not endpoint, we consider it to be correct."""
        vpn = VPNConfiguration.objects.all()[0]
        if vpn.ipv6_endpoint is not None:
            subnet = vpn.ip_subnet.get(ip_pool=self.v6_pool)
            self.assertIn(vpn.ipv6_endpoint, subnet.inet)

    def test_change_v4subnet_is_vpn_endpoint_correct(self):
        vpn = VPNConfiguration.objects.all()[0]
        subnet = vpn.ip_subnet.get(ip_pool=self.v4_pool)
        subnet.inet = "192.168.42.42/31"
        subnet.full_clean()
        subnet.save()
        self.test_has_correct_ipv4_endpoint()

    def test_change_v6subnet_is_vpn_endpoint_correct(self):
        vpn = VPNConfiguration.objects.all()[0]
        subnet = vpn.ip_subnet.get(ip_pool=self.v6_pool)
        subnet.inet = "2001:db8:4242:4200::/56"
        subnet.full_clean()
        subnet.save()
        self.test_has_correct_ipv6_endpoint()

    def test_automatic_login(self):
        vpn = VPNConfiguration.objects.all()[0]
        expected_login = vpn.offersubscription.member.username + "-vpn1"
        self.assertEqual(vpn.login, expected_login)

    def test_has_multiple_vpn(self):
        vpns = VPNConfiguration.objects.all()
        self.assertEqual(len(vpns), 6)