# Copyright © The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""Populate ``worker:build-arch:`` tags from work request data."""

from typing import Any

from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.migrations.state import StateApps

BUILD_ARCH_PREFIX = "worker:build-arch:"

GENERATED_TAGS = [
    BUILD_ARCH_PREFIX + arch
    for arch in ("amd64", "arm64", "ppc64el", "armhf", "armel", "i386")
]


def copy_build_arch_to_tag(
    apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
) -> None:
    """Convert work request build architectures to tags."""
    WorkRequest = apps.get_model("db", "WorkRequest")

    def merge_tag_into(tag: str, wr: Any) -> None:
        """Add tag to tags, in place, keeping it sorted."""
        assert isinstance(wr, WorkRequest)
        wr.scheduler_tags_required.append(tag)
        wr.scheduler_tags_required.sort()
        wr.save()

    # sbuild-like tags using build_architecture
    for wr in (
        WorkRequest.objects.filter(task_data__has_key="build_architecture")
        .exclude(task_data__build_architecture=None)
        .exclude(scheduler_tags_required__overlap=GENERATED_TAGS)
    ):
        tag = BUILD_ARCH_PREFIX + wr.task_data["build_architecture"]
        merge_tag_into(tag, wr)

    # mmdebstrap-like tags using bootstrap_options.architecture
    for wr in (
        WorkRequest.objects.filter(
            task_data__bootstrap_options__has_key="architecture"
        )
        .exclude(task_data__bootstrap_options__architecture=None)
        .exclude(scheduler_tags_required__overlap=GENERATED_TAGS)
    ):
        tag = (
            BUILD_ARCH_PREFIX
            + wr.task_data["bootstrap_options"]["architecture"]
        )
        merge_tag_into(tag, wr)


class Migration(migrations.Migration):
    dependencies = [
        ('db', '0045_alter_workrequest_unblock_strategy'),
    ]

    operations = [
        migrations.RunPython(copy_build_arch_to_tag, migrations.RunPython.noop),
    ]
