# Generated by Django 3.2.2 on 2021-09-15 20:24

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from django.contrib.auth.models import User
from django.db import connection
from resources.models import Project, Role, ProjectAccess, Permission
from resources.management.commands.loadfixtures import load_fixtures


def migrate_property(*args):
    permission_instances = []
    obj_types = ["collection", "resource", "metadata", "metadataset", "file", "tag"]
    permissions = ["add", "read", "write", "delete"]
    for obj_type in obj_types:
        for permission in permissions:
            perm, created = Permission.objects.get_or_create(
                label="{}.{}".format(obj_type, permission)
            )
            permission_instances.append(perm)
    perm, created = Permission.objects.get_or_create(label="file.download_source")
    permission_instances.append(perm)
    for user in User.objects.all():
        project, created = Project.objects.get_or_create(
            label="{} main project".format(user.username)
        )
        admin_role, created = Role.objects.get_or_create(label="admin", project=project)
        for perm in permission_instances:
            admin_role.permissions.add(perm)
        project_access, created = ProjectAccess.objects.get_or_create(
            project=project, role=admin_role, user=user
        )
        with connection.cursor() as cursor:
            cursor.execute(
                "UPDATE resources_collection set project_id = {} where owner_id = {}".format(
                    project.pk, user.pk
                )
            )
            cursor.execute(
                "UPDATE resources_file set project_id = {} where owner_id = {}".format(
                    project.pk, user.pk
                )
            )
            cursor.execute(
                "UPDATE resources_metadata set project_id = {} where owner_id = {}".format(
                    project.pk, user.pk
                )
            )
            cursor.execute(
                "UPDATE resources_metadataset set project_id = {} where owner_id = {}".format(
                    project.pk, user.pk
                )
            )
            cursor.execute(
                "UPDATE resources_resource set ptr_project_id = {} where ptr_owner_id = {}".format(
                    project.pk, user.pk
                )
            )
            cursor.execute(
                "UPDATE resources_tag set project_id = {} where owner_id = {}".format(
                    project.pk, user.pk
                )
            )
    # allow read access to public_project for all users
    # (ie. allow access to exif and OCR metas)
    public_user = User.objects.get(username="public_user")
    public_project = Project.objects.get(projectaccess__user=public_user)
    public_read_role, created = Role.objects.get_or_create(
        label="public_reader", project=public_project
    )
    for permission_label in [
        "collection.read",
        "resource.read",
        "metadata.read",
        "metadataset.read",
        "file.read",
        "tag.read",
    ]:
        permission = Permission.objects.get(label=permission_label)
        public_read_role.permissions.add(permission)


def post_migrate(*args):
    load_fixtures()
    migrate_property()


class Migration(migrations.Migration):
    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ("resources", "0013_collection_is_oai_record"),
    ]

    operations = [
        migrations.CreateModel(
            name="Permission",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("label", models.TextField(unique=True)),
            ],
        ),
        migrations.CreateModel(
            name="Project",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("label", models.TextField()),
                ("description", models.TextField()),
            ],
        ),
        migrations.CreateModel(
            name="Role",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("label", models.TextField()),
                ("permissions", models.ManyToManyField(to="resources.Permission")),
                (
                    "project",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="resources.project",
                    ),
                ),
            ],
            options={
                "unique_together": {("label", "project")},
            },
        ),
        migrations.AddField(
            model_name="collection",
            name="project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AddField(
            model_name="file",
            name="project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AddField(
            model_name="metadata",
            name="project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AddField(
            model_name="metadataset",
            name="project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AddField(
            model_name="resource",
            name="ptr_project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AddField(
            model_name="tag",
            name="project",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                to="resources.project",
            ),
        ),
        migrations.AlterUniqueTogether(
            name="file",
            unique_together={("owner", "hash"), ("project", "hash")},
        ),
        migrations.AlterUniqueTogether(
            name="metadata",
            unique_together={("title", "set", "owner"), ("title", "set", "project")},
        ),
        migrations.AlterUniqueTogether(
            name="metadataset",
            unique_together={("title", "project"), ("title", "owner")},
        ),
        migrations.AlterUniqueTogether(
            name="tag",
            unique_together={("uid", "project"), ("uid", "owner")},
        ),
        migrations.CreateModel(
            name="ProjectAccess",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "project",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="resources.project",
                    ),
                ),
                (
                    "role",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE, to="resources.role"
                    ),
                ),
                (
                    "user",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to=settings.AUTH_USER_MODEL,
                    ),
                ),
            ],
            options={
                "unique_together": {("project", "user", "role")},
            },
        ),
        # migrations.RunPython(post_migrate)
    ]
