import json
from django.test import TestCase
from django.utils import translation
from django.conf import settings
from accrete.models import AccessGroup, Tenant
from accrete.tenant import set_tenant
from accrete.contrib.log import activity
from accrete.contrib.log.models import Activity, Log, LogConfig, LogConfigField
from accrete.contrib.log import helper, queries


class LogTestCase(TestCase):

    def setUp(self):
        super().setUp()
        self.tenant = Tenant(name='Test Tenant', is_active=True)
        self.tenant.save()
        set_tenant(self.tenant)
        self.log_config = LogConfig(
            model='accrete.AccessGroup', 
            exclude_fields=True, 
            ignore_errors=False,
        )
        self.log_config.save()

    def test_activity_context(self):
        group = AccessGroup(code='test', name='Test Group')
        with activity(
            code='test context', 
            description='Test description',
        ) as context:
            group.save()
            self.assertEqual(context.activity.description, 'Test description')
            self.assertTrue(context.activity.logs.exists())
    
    def test_log_specific_fields(self):
        self.log_config.exclude_fields = False
        self.log_config.save()
        LogConfigField.objects.bulk_create([
            LogConfigField(log_config=self.log_config, field_name='name'),
            LogConfigField(log_config=self.log_config, field_name='apply_on'),
        ])
        group = AccessGroup(code='test specific field log')
        with activity(code='test_log_specific') as ctx:
            group.save()
            self.assertEqual(ctx.activity.logs.count(), 2)
        self.log_config.fields.all().delete()
        self.log_config.exclude_fields = True
        self.log_config.save()


    
    def test_instance_state(self):
        translation.activate(settings.LANGUAGE_CODE)
        group = AccessGroup(code='test state', description='Group Description')
        group.save()
        state = helper.get_instance_state(group)
        expected_state = {
            'id': group.pk,
            'code': 'test state',
            'name': json.dumps({settings.LANGUAGE_CODE: ''}),
            'description': json.dumps({settings.LANGUAGE_CODE: 'Group Description'}),
            'apply_on': 'tenant',
        }
        self.assertDictEqual(state, expected_state)
        group.apply_on = 'member'
        group.name = 'Test'
        group.save()
        expected_state.update(
            apply_on='member',
            name=json.dumps({settings.LANGUAGE_CODE: 'Test'})
        )
        state = helper.get_instance_state(group)
        self.assertDictEqual(state, expected_state)
    
    def test_log_state(self):
        translation.activate(settings.LANGUAGE_CODE)
        group = AccessGroup(code='test log state')
        group.save()
        group.description = 'Description'
        group.save()
        log_state = queries.current_log_state('accrete.AccessGroup', group.pk)
        expected = {
            'id': group.pk,
            'code': 'test log state',
            'name': json.dumps({settings.LANGUAGE_CODE: ''}),
            'description': json.dumps({settings.LANGUAGE_CODE: 'Description'}),
            'apply_on': 'tenant',
        }
        self.assertDictEqual(helper.log_state_to_dict(log_state)[0], expected)
