from collections import defaultdict

from django.test import TestCase
from django.contrib.auth.models import AnonymousUser
from django.contrib.auth import get_user_model
from django.views import View
from django.test.client import RequestFactory
from django.conf import settings

from accrete.tenant import set_member, get_member, get_tenant, per_tenant
from accrete.mixins import TenantRequiredMixin
from accrete.models import Tenant, Member

User = get_user_model()


class TenantViewTestCase(TestCase):

    class TestView(TenantRequiredMixin, View):

        pass

    def setUp(self):
        self.factory = RequestFactory()
        self.user = User(email='user@accrete.test', username='Test User')
        self.user.save()
        self.user_without_tenant = User(
            email='test@test.com', username='Test User'
        )
        self.user_without_tenant.save()

    def test_not_logged_in(self):
        request = self.factory.get('/')
        request.user = AnonymousUser()
        view = self.TestView.as_view()
        res = view(request)
        self.assertEqual(res.status_code, 302)

    def test_no_tenant(self):
        request = self.factory.get('/')
        request.user = self.user_without_tenant
        request.tenant = None
        view = self.TestView.as_view()
        res = view(request)
        self.assertTrue(
            res.url.startswith(settings.ACCRETE_TENANT_NOT_SET_URL)
        )

    def test_set_member(self):
        t1 = Tenant(name='Test 1')
        t1.save()
        m1 = Member(tenant=t1, user=self.user)
        m1.save()
        set_member(m1)
        self.assertEqual(get_member(), m1)
        self.assertEqual(get_tenant(), t1)
        set_member(None)
        self.assertEqual(get_member(), None)
        self.assertEqual(get_tenant(), None)

    def test_per_tenant(self):

        @per_tenant()
        def func_per_tenant():
            calls_per_tenant[get_tenant().pk] += 1

        t1 = Tenant(name='Test 1')
        t2 = Tenant(name='Test 1')
        t1.save()
        t2.save()
        calls_per_tenant = defaultdict(int)
        func_per_tenant()
        self.assertDictEqual(calls_per_tenant, {t1.pk: 1,t2.pk: 1})
