# Copyright (C) 2019 Linaro Limited
#
# Author: Stevan Radakovic <stevan.radakovic@linaro.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later

# Generated by Django 1.11.23 on 2019-10-12 16:54

from django.db import migrations, transaction
from django.db.utils import IntegrityError


def forwards_func(apps, schema_editor):
    DeviceType = apps.get_model("lava_scheduler_app", "DeviceType")
    Device = apps.get_model("lava_scheduler_app", "Device")
    TestJob = apps.get_model("lava_scheduler_app", "TestJob")
    User = apps.get_model("auth", "User")
    Group = apps.get_model("auth", "Group")
    Permission = apps.get_model("auth", "Permission")
    ContentType = apps.get_model("contenttypes", "ContentType")
    GroupDeviceTypePermission = apps.get_model(
        "lava_scheduler_app", "GroupDeviceTypePermission"
    )
    GroupDevicePermission = apps.get_model(
        "lava_scheduler_app", "GroupDevicePermission"
    )
    db_alias = schema_editor.connection.alias

    ct_devicetype = ContentType.objects.get_for_model(DeviceType)
    ct_device = ContentType.objects.get_for_model(Device)
    ct_testjob = ContentType.objects.get_for_model(TestJob)

    admin_devicetype_perm, _ = Permission.objects.using(db_alias).get_or_create(
        name="Can admin device type",
        content_type=ct_devicetype,
        codename="admin_devicetype",
    )
    change_devicetype_perm, _ = Permission.objects.using(db_alias).get_or_create(
        name="Can change device type",
        content_type=ct_devicetype,
        codename="change_devicetype",
    )
    admin_device_perm, _ = Permission.objects.using(db_alias).get_or_create(
        name="Can admin device", content_type=ct_device, codename="admin_device"
    )
    change_device_perm, _ = Permission.objects.using(db_alias).get_or_create(
        name="Can change device", content_type=ct_device, codename="change_device"
    )

    try:
        cancel_resubmit_testjob_perm = Permission.objects.using(db_alias).get(
            content_type=ct_testjob, codename="cancel_resubmit_testjob"
        )
    except Permission.DoesNotExist:
        cancel_resubmit_testjob_perm = Permission.objects.using(db_alias).create(
            name="Can cancel or resubmit test jobs",
            content_type=ct_testjob,
            codename="cancel_resubmit_testjob",
        )

    change_testjob_perm, _ = Permission.objects.using(db_alias).get_or_create(
        name="Can change test job", content_type=ct_testjob, codename="change_testjob"
    )

    obsolete_content_type_apps = [
        "dashboard_app",
        "linaro_graphics_app",
        "south",
        "lava_projects",
        "lava_kernel_ci_views_app",
        "djcelery",
        "android_benchmark_views_app",
    ]
    obsolete_cts = ContentType.objects.filter(app_label__in=obsolete_content_type_apps)
    Permission.objects.using(db_alias).filter(content_type__in=obsolete_cts).delete()

    for group in Group.objects.using(db_alias).all():
        if group.permissions.filter(codename="admin_devicetype"):
            group.permissions.add(change_devicetype_perm)
            group.permissions.remove(admin_devicetype_perm)
        if group.permissions.filter(codename="admin_device"):
            group.permissions.add(change_device_perm)
            group.permissions.remove(admin_device_perm)
        if group.permissions.filter(codename="cancel_resubmit_testjob"):
            group.permissions.add(change_testjob_perm)
            group.permissions.remove(cancel_resubmit_testjob_perm)

    for user in User.objects.using(db_alias).all():
        if user.user_permissions.filter(codename="admin_devicetype"):
            user.user_permissions.add(change_devicetype_perm)
            user.user_permissions.remove(admin_devicetype_perm)
        if user.user_permissions.filter(codename="admin_device"):
            user.user_permissions.add(change_device_perm)
            user.user_permissions.remove(admin_device_perm)
        if user.user_permissions.filter(codename="cancel_resubmit_testjob"):
            user.user_permissions.add(change_testjob_perm)
            user.user_permissions.remove(cancel_resubmit_testjob_perm)

    for group_permission in GroupDeviceTypePermission.objects.using(db_alias).filter(
        permission=admin_devicetype_perm
    ):
        try:
            with transaction.atomic():
                group_permission.permission = change_devicetype_perm
                group_permission.save()
        except IntegrityError:
            group_permission.delete()

    for group_permission in GroupDevicePermission.objects.using(db_alias).filter(
        permission=admin_device_perm
    ):
        try:
            with transaction.atomic():
                group_permission.permission = change_device_perm
                group_permission.save()
        except IntegrityError:
            group_permission.delete()

    Permission.objects.using(db_alias).filter(codename="add_testjob").delete()
    Permission.objects.using(db_alias).filter(codename="admin_devicetype").delete()
    Permission.objects.using(db_alias).filter(codename="admin_device").delete()


def noop(apps, schema_editor):
    pass


class Migration(migrations.Migration):
    dependencies = [("lava_scheduler_app", "0045_remove_submit_testjob_perm")]

    operations = [
        migrations.RunPython(forwards_func, noop),
        migrations.AlterModelOptions(
            name="device",
            options={
                "permissions": (
                    ("view_device", "Can view device"),
                    ("submit_to_device", "Can submit jobs to device"),
                )
            },
        ),
        migrations.AlterModelOptions(
            name="devicetype",
            options={
                "permissions": (
                    ("view_devicetype", "Can view device type"),
                    ("submit_to_devicetype", "Can submit jobs to device type"),
                )
            },
        ),
        migrations.AlterModelOptions(
            name="testjob", options={"default_permissions": ("change", "delete")}
        ),
    ]
