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

"""Unit tests for the create_child_workspace workflow."""

from debusine.db.models import WorkRequest, Workspace
from debusine.db.playground import scenarios
from debusine.server.workflows import CreateChildWorkspaceWorkflow
from debusine.server.workflows.base import orchestrate_workflow
from debusine.server.workflows.models import ChildWorkspaceData
from debusine.server.workflows.tests.helpers import WorkflowTestCase
from debusine.tasks.models import BaseDynamicTaskData


class CreateChildWorkspaceWorkflowTests(
    WorkflowTestCase[CreateChildWorkspaceWorkflow]
):
    """Unit tests for :py:class:`CreateChildWorkspaceWorkflow`."""

    SAMPLE_TASK_DATA = {"suffix": "test"}

    scenario = scenarios.DefaultContext()

    def test_compute_scheduler_tags(self) -> None:
        self.assertComputesSchedulerTags()

    def test_compute_dynamic_data(self) -> None:
        self.assertEqual(
            self.compute_dynamic_data(self.task),
            BaseDynamicTaskData(subject="test", parameter_summary="test"),
        )

    def test_get_label_without_parameter_summary(self) -> None:
        """Test get_label."""
        self.task_data["suffix"] = "test_1"

        # Web UI: Do not prepare, just instantiate from the model
        task = self.work_request.get_task()

        self.assertEqual(task.get_label(), "create_child_workspace")

    def test_get_label_with_parameter_summary(self) -> None:
        """Test get_label."""
        root = self.orchestrate(task_data=ChildWorkspaceData(suffix="test_2"))

        self.assertEqual(
            root.get_task().get_label(),
            "create_child_workspace-template: test_2",
        )

    def test_create_orchestrator(self) -> None:
        """Workflow can be instantiated."""
        workflow = self.task
        self.assertIsNone(workflow.data.prefix)
        self.assertEqual(workflow.data.suffix, "test")
        self.assertTrue(workflow.data.public)
        self.assertIsNone(workflow.data.owner_group)
        self.assertEqual(workflow.data.workflow_template_names, [])
        self.assertEqual(workflow.data.expiration_delay, 60)

    def orchestrate(
        self,
        task_data: ChildWorkspaceData,
        *,
        workspace: Workspace | None = None,
    ) -> WorkRequest:
        """Create and orchestrate a CreateChildWorkspaceWorkflow."""
        template = self.playground.create_workflow_template(
            name="create_child_workspace-template",
            task_name="create_child_workspace",
            workspace=workspace,
        )
        root = self.playground.create_workflow(
            task_name="create_child_workspace",
            task_data=task_data.model_dump(mode="json"),
        )
        self.assertEqual(root.workspace, template.workspace)
        self.assertTrue(orchestrate_workflow(root))
        return root

    def test_populate(self) -> None:
        root = self.orchestrate(task_data=ChildWorkspaceData(suffix="test"))
        # There is only one child task
        create_child_workspace = root.children.get()
        self.assertEqual(
            create_child_workspace.task_name, "create_child_workspace"
        )
        self.assertEqual(
            create_child_workspace.task_data,
            {
                "prefix": root.workspace.name,
                "suffix": "test",
                "expiration_delay": 60,
                "owner_group": None,
                "public": True,
                "workflow_template_names": [],
            },
        )

    def test_populate_prefix(self) -> None:
        root = self.orchestrate(
            task_data=ChildWorkspaceData(prefix="namespace", suffix="test")
        )
        # There is only one child task
        create_child_workspace = root.children.get()
        self.assertEqual(
            create_child_workspace.task_name, "create_child_workspace"
        )
        self.assertEqual(
            create_child_workspace.task_data,
            {
                "prefix": "namespace",
                "suffix": "test",
                "expiration_delay": 60,
                "owner_group": None,
                "public": True,
                "workflow_template_names": [],
            },
        )
