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

"""Tests the WorkRequest UI helper."""

from django.test import RequestFactory

from debusine.db.models import WorkRequest
from debusine.db.playground import scenarios
from debusine.test.django import TestCase
from debusine.web.views.ui.work_requests import WorkRequestUI


class WorkRequestUITests(TestCase):
    """Test the :py:class:`WorkRequestUI` class."""

    scenario = scenarios.DefaultContext(set_current=True)

    def ui(self, work_request: WorkRequest) -> WorkRequestUI:
        """Instantiate a UI helper for a workspace."""
        factory = RequestFactory()
        request = factory.get("/")
        return work_request.ui(request)

    def test_label_workflow_invalid_data(self) -> None:
        template = self.playground.create_workflow_template(
            name="test", task_name="noop"
        )
        wr = self.playground.create_workflow(template, task_data={})
        assert wr.configured_task_data is not None
        wr.configured_task_data["invalid"] = True
        wr.save()
        self.assertEqual(self.ui(wr).label, "test")

    def test_label_for_synchronization_point(self) -> None:
        template = self.playground.create_workflow_template(
            name="test", task_name="noop"
        )
        workflow = self.playground.create_workflow(template, task_data={})
        wr = WorkRequest.objects.create_synchronization_point(
            parent=workflow, step="test", display_name="Test"
        )
        self.assertEqual(self.ui(wr).label, "synchronization_point")

    def test_sidebar_work_request_status(self) -> None:
        wr = WorkRequest(status=WorkRequest.Statuses.PENDING)
        el = self.ui(wr).sidebar_work_request_status()
        assert el.value is not None
        self.assertHTMLEqual(
            el.value, '<span class="badge text-bg-secondary">Pending</span>'
        )

        wr = WorkRequest(status=WorkRequest.Statuses.BLOCKED)
        el = self.ui(wr).sidebar_work_request_status()
        assert el.value is not None
        self.assertHTMLEqual(
            el.value, '<span class="badge text-bg-dark">Blocked</span>'
        )

        wr.status, wr.result = (
            WorkRequest.Statuses.COMPLETED,
            WorkRequest.Results.FAILURE,
        )
        el = self.ui(wr).sidebar_work_request_status()
        assert el.value is not None
        self.assertHTMLEqual(
            el.value,
            '<span class="badge text-bg-primary">Completed</span>'
            ' <span class="badge text-bg-warning">Failure</span>',
        )

        wr.status, wr.result = (
            WorkRequest.Statuses.COMPLETED,
            WorkRequest.Results.SKIPPED,
        )
        el = self.ui(wr).sidebar_work_request_status()
        assert el.value is not None
        self.assertHTMLEqual(
            el.value,
            '<span class="badge text-bg-primary">Completed</span>'
            ' <span class="badge text-bg-secondary">Skipped</span>',
        )

        # This case does not make sense but it must be rendered somewhat
        wr.status, wr.result = (
            WorkRequest.Statuses.ABORTED,
            WorkRequest.Results.ERROR,
        )
        el = self.ui(wr).sidebar_work_request_status()
        assert el.value is not None
        self.assertHTMLEqual(
            el.value,
            '<span class="badge text-bg-dark">Aborted</span>'
            ' <span class="badge text-bg-danger">Error</span>',
        )

    def test_sidebar_supersede(self) -> None:
        wr_old = WorkRequest(pk=1, workspace=self.scenario.workspace)
        wr_new = WorkRequest(pk=2, workspace=self.scenario.workspace)
        wr_old.superseded = wr_new

        el = self.ui(wr_old).sidebar_work_request_superseded()
        self.assertEqual(el.value, "2")
        el = self.ui(wr_old).sidebar_work_request_supersedes()
        self.assertIsNone(el.value)
        el = self.ui(wr_new).sidebar_work_request_superseded()
        self.assertIsNone(el.value)
        el = self.ui(wr_new).sidebar_work_request_supersedes()
        self.assertEqual(el.value, "1")
