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

from unittest import skipUnless

from django.test import TestCase
from django.conf import settings

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 VPSConfiguration

USING_POSTGRES = (settings.DATABASES['default']['ENGINE']
                  ==
                  'django.db.backends.postgresql_psycopg2')

class VPSTestCase(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="VPSConfiguration")[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 VPS 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()
        vps = VPSConfiguration(offersubscription=abo)
        vps.full_clean()
        vps.save()
        v6 = IPSubnet(ip_pool=self.v6_pool, configuration=vps)
        v6.full_clean()
        v6.save()
        v4 = IPSubnet(ip_pool=self.v4_pool, configuration=vps)
        v4.full_clean()
        v4.save()

        # Create additional VPS, 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()
            vps = VPSConfiguration(offersubscription=abo)
            vps.full_clean()
            vps.save()

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

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_has_ipv4_endpoint(self):
        vps = VPSConfiguration.objects.all()[0]
        self.assertIsNotNone(vps.ipv4_endpoint)

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_has_correct_ipv4_endpoint(self):
        """If there is not endpoint, we consider it to be correct."""
        vps = VPSConfiguration.objects.all()[0]
        if vps.ipv4_endpoint is not None:
            subnet = vps.ip_subnet.get(ip_pool=self.v4_pool)
            self.assertIn(vps.ipv4_endpoint, subnet.inet)

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_has_ipv6_endpoint(self):
        vps = VPSConfiguration.objects.all()[0]
        self.assertIsNotNone(vps.ipv6_endpoint)

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_has_correct_ipv6_endpoint(self):
        """If there is not endpoint, we consider it to be correct."""
        vps = VPSConfiguration.objects.all()[0]
        if vps.ipv6_endpoint is not None:
            subnet = vps.ip_subnet.get(ip_pool=self.v6_pool)
            self.assertIn(vps.ipv6_endpoint, subnet.inet)

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_change_v4subnet_is_vps_endpoint_correct(self):
        vps = VPSConfiguration.objects.all()[0]
        subnet = vps.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()

    @skipUnless(USING_POSTGRES, "Using a postgresql-only field")
    def test_change_v6subnet_is_vps_endpoint_correct(self):
        vps = VPSConfiguration.objects.all()[0]
        subnet = vps.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):
        vps = VPSConfiguration.objects.all()[0]
        expected_login = vps.offersubscription.member.username + "-vps1"
        self.assertEqual(vps.login, expected_login)

    def test_has_multiple_vps(self):
        vpss = VPSConfiguration.objects.all()
        self.assertEqual(len(vpss), 6)