# Generated by Django 5.2.7 on 2025-11-11 14:13

import re

from django.contrib.postgres.aggregates import ArrayAgg
from django.db import migrations
from django.db.models import Min


def set_cc(apps, schema_editor):
    License = apps.get_model("epdb", "License")

    # For all existing licenses extract cc_string from link
    for license in License.objects.all():
        pattern = r"/licenses/([^/]+)/4\.0"
        match = re.search(pattern, license.link)
        if match:
            license.cc_string = match.group(1)
            license.save()
        else:
            raise ValueError(f"Could not find license for {license.link}")

    # Ensure we have all licenses
    cc_strings = ["by", "by-nc", "by-nc-nd", "by-nc-sa", "by-nd", "by-sa"]
    for cc_string in cc_strings:
        if not License.objects.filter(cc_string=cc_string).exists():
            new_license = License()
            new_license.cc_string = cc_string
            new_license.link = f"https://creativecommons.org/licenses/{cc_string}/4.0/"
            new_license.image_link = f"https://licensebuttons.net/l/{cc_string}/4.0/88x31.png"
            new_license.save()

    # As we might have existing Licenses representing the same License,
    # get min pk and all pks as a list
    license_lookup_qs = License.objects.values("cc_string").annotate(
        lowest_pk=Min("id"), all_pks=ArrayAgg("id", order_by=("id",))
    )

    license_lookup = {
        row["cc_string"]: (row["lowest_pk"], row["all_pks"]) for row in license_lookup_qs
    }

    Packages = apps.get_model("epdb", "Package")

    for k, v in license_lookup.items():
        # Set min pk to all packages pointing to any of the duplicates
        Packages.objects.filter(pk__in=v[1]).update(license_id=v[0])
        # remove the min pk from "other" pks as we use them for deletion
        v[1].remove(v[0])
        # Delete redundant License objects
        License.objects.filter(pk__in=v[1]).delete()


class Migration(migrations.Migration):
    dependencies = [
        ("epdb", "0010_license_cc_string"),
    ]

    operations = [migrations.RunPython(set_cc)]
