# Copyright 2024 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 for task status view."""
from django.template.loader import get_template
from django.test import RequestFactory, override_settings
from django.urls import reverse

from debusine.db.models import WorkRequest
from debusine.tasks.models import WorkerType
from debusine.test.django import TestCase
from debusine.web.views.tests.utils import ViewTestMixin


class TaskStatusViewTests(ViewTestMixin, TestCase):
    """Tests for TaskStatusView."""

    def setUp(self):
        """Set up objects."""
        self.factory = RequestFactory()

    def test_template_no_work_requests(self):
        """Test template display the "No work requests..." message."""
        response = self.client.get(reverse("task-status"))

        self.assertContains(
            response, "<p>There are no pending work requests.</p>", html=True
        )

    @override_settings(DISABLE_AUTOMATIC_SCHEDULING=True)
    def test_template(self):
        """Test template contains expected output."""
        worker = self.playground.create_worker(
            worker_type=WorkerType.EXTERNAL,
            extra_dynamic_metadata={
                "system:host_architecture": "amd64",
                "system:architectures": ["amd64", "i386"],
            },
        )
        worker.mark_connected()

        self.playground.create_work_request(
            task_name="noop",
            task_data={"host_architecture": "amd64"},
            status=WorkRequest.Statuses.PENDING,
        )
        self.playground.create_work_request(task_name="sbuild")

        response = self.client.get(reverse("task-status"))

        tree = self.assertHTMLValid(response)

        table = tree.xpath("//table[@id='build-queue']")[0]

        # First row: architecture amd64, 1 connected worker, 1 work request
        row = table.tbody.tr[0]
        work_request_list_amd64 = (
            reverse("work_requests:list") + "?status=pending&amp;arch=amd64"
        )
        self.assertHTMLContentsEquivalent(
            row.td[0], f'<td><a href="{work_request_list_amd64}">amd64</a></td>'
        )
        self.assertHTMLContentsEquivalent(row.td[1], "<td>1</td>")
        self.assertHTMLContentsEquivalent(row.td[2], "<td>1</td>")

        # Second row: architecture i386, 1 connected worker, 0 work requests
        row = table.tbody.tr[1]
        work_request_list_i386 = (
            reverse("work_requests:list") + "?status=pending&amp;arch=i386"
        )
        self.assertHTMLContentsEquivalent(
            row.td[0], f'<td><a href="{work_request_list_i386}">i386</a></td>'
        )
        self.assertHTMLContentsEquivalent(row.td[1], "<td>1</td>")
        self.assertHTMLContentsEquivalent(row.td[2], "<td>0</td>")

        # Two rows for two architectures: amd64 and i386
        self.assertEqual(len(table.tbody.tr), 2)

    def test_task_queue_sorted_in_template(self):
        """task_queue is sorted by architecture in the template."""
        # Create an unsorted task_queue dictionary
        task_queue = {
            "i386": {"workers": 3, "work_requests_pending": 5},
            "amd64": {"workers": 2, "work_requests_pending": 3},
        }
        template = get_template("web/task_status.html")
        rendered_html = template.render({"task_queue": task_queue})

        i386_index = rendered_html.find("i386")
        amd64_index = rendered_html.find("amd64")

        self.assertLess(amd64_index, i386_index)
