from books.factories import ModuleFactory, ChapterFactory
from books.management.commands.migrate_objectives_to_content import migrate_objectives_to_content
from books.tests.queries import MODULE_QUERY
from core.tests.base_test import SkillboxTestCase
from objectives.factories import ObjectiveGroupFactory, ObjectiveFactory
from users.models import User, SchoolClass


class TestObjectivesMigration(SkillboxTestCase):
    @property
    def graphene_client(self):
        return self.get_client()

    def setUp(self):
        self.createDefault()
        self.client = self.get_client()
        # teacher will create snapshot
        self.slug = 'some-module'

        self.module = ModuleFactory(slug=self.slug)
        self.skillbox_class = SchoolClass.objects.get(name='skillbox')
        self.teacher2 = User.objects.get(username='teacher2')
        self.second_class_name = 'second_class'
        self.second_class = SchoolClass.objects.get(name=self.second_class_name)
        self.admin = User.objects.get(username='admin')

        # we make a snapshot S of the module M
        # snapshot S looks like module M for school class X
        # module M has a chapter
        self.chapter = ChapterFactory(parent=self.module, slug='some-chapter', owner=self.admin)
        ChapterFactory(parent=self.module, slug='some-other-chapter', owner=self.admin)

        objective_group = ObjectiveGroupFactory(module=self.module, title='society')

        self.visible_objective = ObjectiveFactory(text='visible-objective', group=objective_group)
        self.hidden_objective = ObjectiveFactory(text='hidden-objective', group=objective_group)
        self.hidden_objective.hidden_for.add(self.skillbox_class)
        self.hidden_objective.save()
        self.custom_objective = ObjectiveFactory(text='custom-objective', group=objective_group, owner=self.teacher)
        self.custom_objective.visible_for.add(self.skillbox_class)
        self.custom_objective.save()
        self.custom_hidden_objective = ObjectiveFactory(text='custom-hidden-objective', group=objective_group,
                                                        owner=self.teacher)
        self.custom_hidden_objective.visible_for.remove(self.skillbox_class)

        second_objective_group = ObjectiveGroupFactory(module=self.module, title='language_communication')
        self.visible_objective = ObjectiveFactory(text='objective1', group=second_objective_group)
        second_objective_group.hidden_for.add(self.skillbox_class)
        second_objective_group.save()

        third_objective_group = ObjectiveGroupFactory(module=self.module, title='interdisciplinary')
        self.visible_objective_hidden_group_3 = ObjectiveFactory(text='objective1', group=third_objective_group)
        self.hidden_objective_hidden_group_3 = ObjectiveFactory(text='objective2', group=third_objective_group,
                                                                owner=self.teacher)
        self.hidden_objective_hidden_group_3.visible_for.add(self.skillbox_class)
        self.hidden_objective_hidden_group_3.save()

        third_objective_group.hidden_for.add(self.skillbox_class)
        third_objective_group.save()

        migrate_objectives_to_content()

    def test_objectives_migration_hidden_default_content(self):
        result = self.client.execute(MODULE_QUERY, variables={
            'slug': self.module.slug
        })
        module = result.data['module']
        chapter1 = module['chapters'][0]
        _, default_content, _, _, _ = chapter1['contentBlocks']

        # default content block (Verlagsinhalte) exists but is hidden (since one objective is hidden for this class)
        self.assertEqual(default_content['title'], 'Gesellschaft')
        self.assertEqual(default_content['originalCreator'], None)
        self.assertEqual(default_content['contents'][0]['value']['text'],
                         '<ul><li>visible-objective</li><li>hidden-objective</li></ul>')
        self.assertEqual(default_content['hiddenFor'], [{'name': 'skillbox'}])

    def test_objectives_migration_hidden_default_content_creates_custom_content(self):
        result = self.client.execute(MODULE_QUERY, variables={
            'slug': self.module.slug
        })
        module = result.data['module']
        chapter1 = module['chapters'][0]
        _, _, custom, _, _ = chapter1['contentBlocks']

        # default content block (Verlagsinhalte) exists but is hidden (since one objective is hidden for this class)
        self.assertEqual(custom['title'], 'Gesellschaft')
        self.assertTrue(custom['originalCreator'] is not None)
        self.assertEqual(custom['hiddenFor'], [])
        self.assertEqual(custom['visibleFor'], [{'name': 'skillbox'}])
        self.assertEqual(custom['contents'][0]['value']['text'],
                         '<ul><li>visible-objective</li><li>custom-objective</li></ul>')

    def test_objectives_migration_hidden_default_content_creates_hidden_content_block(self):
        result = self.client.execute(MODULE_QUERY, variables={
            'slug': self.module.slug
        })
        module = result.data['module']
        chapter1 = module['chapters'][0]
        hidden_default, _, _, _, _ = chapter1['contentBlocks']

        # default content block (Verlagsinhalte) exists but is hidden (since one objective is hidden for this class)
        self.assertEqual(hidden_default['title'], 'Sprache & Kommunikation')
        self.assertTrue(hidden_default['originalCreator'] is None)
        self.assertEqual(hidden_default['hiddenFor'], [{'name': 'skillbox'}])
        self.assertEqual(hidden_default['visibleFor'], [])
        self.assertEqual(hidden_default['contents'][0]['value']['text'], '<ul><li>objective1</li></ul>')

    def test_objectives_order(self):
        """The correct oder of the objectives is:
        - Sprache & Kommunikation
        - Gesellschaft
        - Übergeordnete Lernziele
        """

        result = self.client.execute(MODULE_QUERY, variables={
            'slug': self.module.slug
        })
        module = result.data['module']
        chapter1 = module['chapters'][0]
        titles = [content['title'] for content in chapter1['contentBlocks']]
        self.assertEqual(titles, ['Sprache & Kommunikation', 'Gesellschaft', 'Gesellschaft', 'Überfachliche Lernziele',
                                  'Überfachliche Lernziele'])

    def test_objectives_migration_hidden_group_custom_content(self):
        result = self.client.execute(MODULE_QUERY, variables={
            'slug': self.module.slug
        })
        module = result.data['module']
        chapter1 = module['chapters'][0]
        _, _, _, _, hidden_custom_group = chapter1['contentBlocks']

        # default content block (Verlagsinhalte) exists but is hidden (since one objective is hidden for this class)
        self.assertEqual(hidden_custom_group['title'], 'Überfachliche Lernziele')
        self.assertTrue(hidden_custom_group['originalCreator'] is not None)
        self.assertEqual(hidden_custom_group['hiddenFor'], [{'name': 'skillbox'}])
        self.assertEqual(hidden_custom_group['visibleFor'], [])
        self.assertEqual(hidden_custom_group['contents'][0]['value']['text'],
                         '<ul><li>objective1</li><li>objective2</li></ul>')
