import contextlib

from django.test import Client, TestCase
from django.urls import reverse

from corehq.apps.app_manager.models import Application
from corehq.apps.cloudcare.views import FormplayerMain
from corehq.apps.dashboard.views import DomainDashboardView
from corehq.apps.domain.models import Domain
from corehq.apps.users.dbaccessors import delete_all_users
from corehq.apps.users.models import (
    CommCareUser,
    Permissions,
    UserRole,
    WebUser,
)
from corehq.util.test_utils import flag_enabled, generate_cases

DOMAIN = 'temerant'


class TestDefaultLandingPages(TestCase):

    @classmethod
    def setUpClass(cls):
        delete_all_users()
        cls.client = Client()

        cls.domain = DOMAIN
        cls.domain_object = Domain(name=cls.domain, is_active=True)
        cls.domain_object.save()

        cls.reports_role = UserRole(
            domain=cls.domain, name='reports-role', default_landing_page='reports',
            permissions=Permissions(view_reports=True),
        )
        cls.reports_role.save()
        cls.webapps_role = UserRole(
            domain=cls.domain, name='webapps-role', default_landing_page='webapps',
            permissions=Permissions(access_web_apps=True),
        )
        cls.webapps_role.save()
        cls.downloads_role = UserRole(
            domain=cls.domain, name='webapps-role', default_landing_page='downloads',
            permissions=Permissions.max(),
        )
        cls.downloads_role.save()
        cls.global_password = 'secret'

        # make an app because not having one changes the default dashboard redirect to the apps page
        app = Application.new_app(domain=cls.domain, name='sympathy')
        app.save()

    def _make_web_user(self, username, role=None, override_domain=None):
        domain = override_domain or self.domain
        web_user = WebUser.create(domain, username, self.global_password, None, None)
        web_user.eula.signed = True
        if role:
            web_user.set_role(domain, role.get_qualified_id())
        web_user.save()
        return web_user

    def _make_commcare_user(self, username, role=None, override_domain=None):
        domain = override_domain or self.domain
        web_user = CommCareUser.create(domain, username, self.global_password, None, None)
        web_user.eula.signed = True
        if role:
            web_user.set_role(domain, role.get_qualified_id())
        web_user.save()
        return web_user

    @classmethod
    def tearDownClass(cls):
        cls.domain_object.delete()

    def test_no_role_cant_access(self):
        user = self._make_web_user('elodin@theuniversity.com')
        self.addCleanup(user.delete, deleted_by=None)
        user.delete_domain_membership(self.domain)
        user.save()
        self.client.login(username=user.username, password=self.global_password)
        response = self.client.get(reverse("domain_homepage", args=[self.domain]), follow=True)
        self.assertEqual(response.status_code, 404)

    def test_formplayer_default_override(self):
        web_user = self._make_web_user('elodin@theuniversity.com', role=self.webapps_role)
        self.addCleanup(web_user.delete, deleted_by=None)
        mobile_worker = self._make_commcare_user('kvothe')
        self.addCleanup(mobile_worker.delete, deleted_by=None)
        for user in [web_user, mobile_worker]:
            self.client.login(username=user.username, password=self.global_password)

            response = self.client.get(reverse("domain_homepage", args=[self.domain]), follow=True)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(reverse(FormplayerMain.urlname, args=[self.domain]),
                             response.request['PATH_INFO'])


@generate_cases([
    (None, DomainDashboardView.urlname),
    ('reports_role', "reports_home"),
    ('webapps_role', FormplayerMain.urlname),
    ('downloads_role', DomainDashboardView.urlname),
    ('downloads_role', 'download_data_files', 'DATA_FILE_DOWNLOAD'),
], TestDefaultLandingPages)
def test_web_user_landing_page(self, role, expected_urlname, enabled_toggle=None):
    if role is not None:
        role = getattr(self, role)
    user = self._make_web_user('elodin@theuniversity.com', role=role)
    self.addCleanup(user.delete, deleted_by=None)
    self.client.login(username=user.username, password=self.global_password)

    context = flag_enabled(enabled_toggle) if enabled_toggle else contextlib.suppress()  # noop context
    with context:
        response = self.client.get(reverse("domain_homepage", args=[self.domain]), follow=True)
    self.assertEqual(response.status_code, 200)
    self.assertEqual(reverse(expected_urlname, args=[self.domain]),
                     response.request['PATH_INFO'])


@generate_cases([
    (None, FormplayerMain.urlname),
    ('reports_role', "reports_home"),
    ('webapps_role', FormplayerMain.urlname),
    ('downloads_role', FormplayerMain.urlname),
    ('downloads_role', 'download_data_files', 'DATA_FILE_DOWNLOAD'),
], TestDefaultLandingPages)
def test_mobile_worker_landing_page(self, role, expected_urlname, enabled_toggle=None):
    if role is not None:
        role = getattr(self, role)
    user = self._make_commcare_user('kvothe', role=role)
    self.addCleanup(user.delete, deleted_by=None)
    self.client.login(username=user.username, password=self.global_password)

    context = flag_enabled(enabled_toggle) if enabled_toggle else contextlib.suppress()  # noop context
    with context:
        response = self.client.get(reverse("domain_homepage", args=[self.domain]), follow=True)
    self.assertEqual(response.status_code, 200)
    self.assertEqual(reverse(expected_urlname, args=[self.domain]),
                     response.request['PATH_INFO'])

@@ -438,16 +438,19 @@
 ns,%0A    
+SQL
 UserRole
@@ -451,16 +451,16 @@
 erRole,%0A
-
     WebU
@@ -848,32 +848,35 @@
 orts_role = 
+SQL
 UserRole
 (%0A          
@@ -855,32 +855,39 @@
 le = SQLUserRole
+.create
 (%0A            do
@@ -1026,40 +1026,8 @@
   )%0A
-        cls.reports_role.save()%0A
     
@@ -1045,32 +1045,35 @@
 apps_role = 
+SQL
 UserRole
 (%0A          
@@ -1052,32 +1052,39 @@
 le = SQLUserRole
+.create
 (%0A            do
@@ -1226,40 +1226,8 @@
   )%0A
-        cls.webapps_role.save()%0A
     
@@ -1251,24 +1251,27 @@
 _role = 
+SQL
 UserRole
 (%0A      
@@ -1262,16 +1262,23 @@
 UserRole
+.create
 (%0A      
@@ -1400,16 +1400,16 @@
 .max(),%0A
+
         
@@ -1414,42 +1414,8 @@
   )%0A
-        cls.downloads_role.save()%0A
     

use sql role in landing page tets