# Generated by Django 3.2.15 on 2022-09-18 15:38
from __future__ import annotations

import os
import os.path as osp
import uuid
from pathlib import Path
from typing import TYPE_CHECKING

from django.db import migrations, models

if TYPE_CHECKING:
    from academic_community.uploaded_material.models import Material


def move_material(apps, schema_editor):
    """Move all files of material to the material subfolder."""
    Material = apps.get_model("uploaded_material", "Material")
    for material in Material.objects.all():
        if material.upload_material:
            old_path = material.upload_material.path
            parts = list(Path(material.upload_material.name).parts)
            parts[1] = "material"
            parts[2] = str(material.uuid)
            material.upload_material.name = osp.join(*parts)
            new_path = material.upload_material.path
            os.makedirs(osp.dirname(new_path), exist_ok=True)
            if not osp.exists(new_path):
                os.rename(old_path, new_path)
            material.save()


def get_implementation_for_object(apps, material: Material) -> Material:
    models = [
        apps.get_model("activities", "activitymaterial"),
        apps.get_model("programme", "sessionmaterial"),
        apps.get_model("programme", "contributionmaterial"),
        apps.get_model("topics", "topicmaterial"),
        apps.get_model("uploaded_material", "communitymaterial"),
        apps.get_model("uploaded_material", "material"),
    ]
    for model in models:
        try:
            return model.objects.get(pk=material.pk)
        except model.DoesNotExist:
            pass


def undo_move_material(apps, schema_editor):
    """Undo the move of the material"""
    Material = apps.get_model("uploaded_material", "Material")
    for material in Material.objects.all():
        if material.upload_material:
            old_path = material.upload_material.path
            parts = list(Path(material.upload_material.name).parts)
            implementation = get_implementation_for_object(apps, material)
            parts[1] = implementation._meta.model_name.lower()
            parts[2] = str(material.pk)
            material.upload_material.name = osp.join(*parts)
            new_path = material.upload_material.path
            os.makedirs(osp.dirname(new_path), exist_ok=True)
            if not osp.exists(new_path):
                os.rename(old_path, new_path)
            material.save()


class Migration(migrations.Migration):

    dependencies = [
        ("uploaded_material", "0008_generate_uuids"),
    ]

    operations = [
        migrations.AlterField(
            model_name="material",
            name="uuid",
            field=models.UUIDField(
                db_index=True,
                default=uuid.uuid4,
                help_text="The uuid of the material",
                unique=True,
            ),
        ),
        migrations.RunPython(move_material, undo_move_material),
    ]
