# use some undocumented Django tricks to execute custom logic after syncdb

from django.db.models import signals
from django.contrib import auth
from django.conf import settings
# In this file, it is critical that we import models *just like this*.  In
# particular, we *cannot* do import common; from autotest_lib... import models.
# This is because when we pass the models module to signal.connect(), it
# calls id() on the module, and the id() of a module can differ depending on how
# it was imported.  For that reason, we must import models as Django does -- not
# through the autotest_lib magic set up through common.py.  If you do that, the
# connection won't work and the dispatcher will simply never call the method.
from frontend.afe import models

BASIC_ADMIN = 'Basic admin'

def create_admin_group(app, created_models, verbosity, **kwargs):
    """\
    Create a basic admin group with permissions for managing basic autotest
    objects.
    """
    admin_group, created = auth.models.Group.objects.get_or_create(
        name=BASIC_ADMIN)
    admin_group.save() # must save before adding permissions
    PermissionModel = auth.models.Permission
    have_permissions = list(admin_group.permissions.all())
    for model_name in ('host', 'label', 'test', 'aclgroup', 'profiler',
                       'atomicgroup', 'hostattribute'):
        for permission_type in ('add', 'change', 'delete'):
            codename = permission_type + '_' + model_name
            permissions = list(PermissionModel.objects.filter(
                codename=codename))
            if len(permissions) == 0:
                if verbosity:
                    print '  No permission ' + codename
                continue
            for permission in permissions:
                if permission not in have_permissions:
                    if verbosity:
                        print '  Adding permission ' + codename
                    admin_group.permissions.add(permission)
    if verbosity:
        if created:
            print 'Created group "%s"' % BASIC_ADMIN
        else:
            print 'Group "%s" already exists' % BASIC_ADMIN

if settings.AUTOTEST_CREATE_ADMIN_GROUPS:
    signals.post_syncdb.connect(create_admin_group, sender=models)
