# 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.

"""Rename ``create_experiment_workspace`` to ``create_child_workspace``."""

import copy

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

from debusine.artifacts.models import TaskTypes


def rename_create_child_workspace_forward(
    apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
) -> None:
    """Rename relevant rows and adjust their data."""
    WorkRequest = apps.get_model("db", "WorkRequest")
    WorkflowTemplate = apps.get_model("db", "WorkflowTemplate")
    for wr in WorkRequest.objects.filter(
        task_type=TaskTypes.SERVER, task_name="create_experiment_workspace"
    ):
        wr.task_name = "create_child_workspace"
        for field in ("task_data", "configured_task_data"):
            if (data := copy.deepcopy(getattr(wr, field))) is not None:
                data["prefix"] = wr.workspace.name
                data["suffix"] = data.pop("experiment_name", None)
                setattr(wr, field, data)
        wr.save()
    for wr in WorkRequest.objects.filter(
        task_type=TaskTypes.WORKFLOW, task_name="create_experiment_workspace"
    ):
        wr.task_name = "create_child_workspace"
        for field in ("task_data", "configured_task_data"):
            if (data := copy.deepcopy(getattr(wr, field))) is not None:
                # The default behaviour if we leave prefix unset is reasonable.
                data["suffix"] = data.pop("experiment_name", None)
                setattr(wr, field, data)
        wr.save()
    for wt in WorkflowTemplate.objects.filter(
        task_name="create_experiment_workspace"
    ):
        wt.task_name = "create_child_workspace"
        for field in ("static_parameters", "runtime_parameters"):
            # Neither of these fields can be None.
            data = copy.deepcopy(getattr(wt, field))
            # prefix is a new field, but we deliberately don't add it to
            # runtime_parameters; the most reasonable default is for it not
            # to be user-configurable.
            if "experiment_name" in data:
                data["suffix"] = data.pop("experiment_name")
            setattr(wt, field, data)
        wt.save()


def rename_create_child_workspace_reverse(
    apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
) -> None:
    """Restore relevant rows to their previous state where possible."""
    WorkRequest = apps.get_model("db", "WorkRequest")
    WorkflowTemplate = apps.get_model("db", "WorkflowTemplate")
    for wr in WorkRequest.objects.filter(
        task_type=TaskTypes.SERVER, task_name="create_child_workspace"
    ):
        wr.task_name = "create_experiment_workspace"
        for field in ("task_data", "configured_task_data"):
            if (data := copy.deepcopy(getattr(wr, field))) is not None:
                data.pop("prefix", None)
                data["experiment_name"] = data.pop("suffix", None)
                setattr(wr, field, data)
        wr.save()
    for wr in WorkRequest.objects.filter(
        task_type=TaskTypes.WORKFLOW, task_name="create_child_workspace"
    ):
        wr.task_name = "create_experiment_workspace"
        for field in ("task_data", "configured_task_data"):
            if (data := copy.deepcopy(getattr(wr, field))) is not None:
                data.pop("prefix", None)
                data["experiment_name"] = data.pop("suffix", None)
                setattr(wr, field, data)
        wr.save()
    for wt in WorkflowTemplate.objects.filter(
        task_name="create_child_workspace"
    ):
        wt.task_name = "create_experiment_workspace"
        for field in ("static_parameters", "runtime_parameters"):
            # Neither of these fields can be None.
            data = copy.deepcopy(getattr(wt, field))
            data.pop("prefix", None)
            if "suffix" in data:
                data["experiment_name"] = data.pop("suffix")
            setattr(wt, field, data)
        wt.save()


class Migration(migrations.Migration):
    dependencies = [
        ("db", "0035_alter_workrequest_status"),
    ]

    operations = [
        migrations.RunPython(
            rename_create_child_workspace_forward,
            rename_create_child_workspace_reverse,
        )
    ]
