# Generated by Django 3.2.18 on 2023-03-15 17:19

from django.db import migrations

from nautobot.core.models.fields import slugify_dashes_to_underscores
from nautobot.extras.constants import JOB_MAX_NAME_LENGTH


def generate_unique_job_names(apps, schema_editor):
    """
    Make duplicate Job names unique by appending an incrementing counter to the end.
    """
    Job = apps.get_model("extras", "Job")
    job_names = []
    for job_model in Job.objects.all().order_by("created"):
        original_job_name = job_model.name
        job_name = original_job_name
        append_counter = 2
        while job_name in job_names:
            job_name_append = f" ({append_counter})"
            max_name_length = JOB_MAX_NAME_LENGTH - len(job_name_append)
            job_name = original_job_name[:max_name_length] + job_name_append
            append_counter += 1
        if job_name != original_job_name:
            print(
                f'  Job class "{job_model.job_class_name}" name "{original_job_name}" is not unique, changing to "{job_name}".'
            )
            job_model.name = job_name
            job_model.name_override = True
        job_model.save()
        job_names.append(job_name)


def fixup_job_module_names(apps, schema_editor):
    """
    Fix up the `module_name` of Jobs to reflect the pending removal of the `source` and `git_repository` fields.
    """
    Job = apps.get_model("extras", "Job")
    # Local jobs, plugin jobs, and system jobs already have the right module name, just need to fix up git jobs
    for job_model in Job.objects.filter(git_repository__isnull=False):
        job_model.module_name = f"{job_model.git_repository.slug}.jobs.{job_model.module_name}"
        job_model.save()


def reverse_fixup_job_module_names(apps, schema_editor):
    GitRepository = apps.get_model("extras", "GitRepository")
    Job = apps.get_model("extras", "Job")
    for repo in GitRepository.objects.all():
        if "extras.job" not in repo.provided_contents:
            continue
        for job_model in Job.objects.filter(module_name__istartswith=f"{repo.slug}.jobs."):
            job_model.source = "git"
            job_model.git_repository = repo
            job_model.module_name = job_model.module.name.replace(f"{repo.slug}.jobs.", "")
            job_model.save()


def update_slug_for_git_repository(apps, schema_editor):
    """
    Update GitRepository.slug to be Python package name safe via slugify_dashes_to_underscores().
    """
    GitRepository = apps.get_model("extras", "GitRepository")
    for git_repository in GitRepository.objects.all():
        git_repository.slug = slugify_dashes_to_underscores(git_repository.slug)
        git_repository.save()


class Migration(migrations.Migration):
    dependencies = [
        ("extras", "0072_rename_model_fields"),
    ]

    operations = [
        migrations.RunPython(
            code=generate_unique_job_names,
            reverse_code=migrations.operations.special.RunPython.noop,
        ),
        migrations.RunPython(
            code=update_slug_for_git_repository,
            reverse_code=migrations.operations.special.RunPython.noop,
        ),
        migrations.RunPython(
            code=fixup_job_module_names,
            reverse_code=reverse_fixup_job_module_names,
        ),
    ]
