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

"""Debusine URL helpers tests."""

from importlib import reload
from typing import override

from django.test import override_settings
from django.urls import clear_url_caches, reverse, set_urlconf
from django.urls.exceptions import NoReverseMatch

import debusine.project.urls
from debusine.test.django import TestCase
from debusine.web.urls.url_utils import (
    make_absolute_archives,
    make_absolute_webui,
    urlconf_archives,
)


@override_settings(DEBUSINE_URL_SCHEME="test_scheme", DEBUSINE_FQDN="test_fqdn")
class MakeAbsoluteWebuiTests(TestCase):
    """Tests for :py:func:`make_absolute_webui`."""

    def test_make_absolute_webui(self) -> None:
        self.assertEqual(
            make_absolute_webui("/foo/bar"), "test_scheme://test_fqdn/foo/bar"
        )


@override_settings(
    DEBUSINE_DEBIAN_ARCHIVE_URL_SCHEME="test_scheme",
    DEBUSINE_DEBIAN_ARCHIVE_PRIMARY_FQDN="test_fqdn",
)
class MakeAbsoluteArchivesTests(TestCase):
    """Tests for :py:func:`make_absolute_archives`."""

    def test_normal(self) -> None:
        self.assertEqual(
            make_absolute_archives("/foo/bar"),
            "test_scheme://test_fqdn/foo/bar",
        )

    @override_settings(DEBUG=True)
    def test_debug(self) -> None:
        self.assertEqual(
            make_absolute_archives("/foo/bar"),
            "/-/__archives__/foo/bar",
        )


class UrlconfArchivesTests(TestCase):
    """Tests for :py:func:`urlconf_archives`."""

    @override
    def setUp(self) -> None:
        super().setUp()

        # The current urlconf is set by setting up the request, but when
        # testing URLs outside of requests it helps to have it reset to a
        # default state, in case a previous test request has left it set to
        # some non-default one
        set_urlconf(None)
        # Clear the urlconf resolver cache, as some urlconfs may have different
        # entries depending on settings
        clear_url_caches()
        reload(debusine.project.urls)

    @override
    def tearDown(self) -> None:
        # Since we reload project urls with DEBUG=True, reload it afterwards to
        # get its default value
        clear_url_caches()
        reload(debusine.project.urls)
        super().tearDown()

    def test_reverse_default(self) -> None:
        self.assertEqual(reverse("homepage:homepage"), "/")
        self.assertEqual(reverse("theme-selection"), "/-/theme/")
        with self.assertRaises(NoReverseMatch):
            reverse(
                "archive-root",
                kwargs={"scope": "testscope", "workspace": "testworkspace"},
            )

    def test_reverse_in_archives(self) -> None:
        with urlconf_archives():
            with self.assertRaises(NoReverseMatch):
                self.assertEqual(reverse("homepage:homepage"), "/")
            self.assertEqual(reverse("theme-selection"), "/-/theme/")
            self.assertEqual(
                reverse(
                    "archive-root",
                    kwargs={"scope": "testscope", "workspace": "testworkspace"},
                ),
                "/testscope/testworkspace/",
            )

    @override_settings(DEBUG=True)
    def test_reverse_in_debug_archives(self) -> None:
        reload(debusine.project.urls)
        with urlconf_archives():
            with self.assertRaises(NoReverseMatch):
                self.assertEqual(reverse("homepage:homepage"), "/")
            self.assertEqual(reverse("theme-selection"), "/-/theme/")
            self.assertEqual(
                reverse(
                    "archive-root",
                    kwargs={"scope": "testscope", "workspace": "testworkspace"},
                ),
                "/testscope/testworkspace/",
            )
