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

"""Template tag library for archive pages."""

from typing import override

from django import template
from django.template import Context, TemplateSyntaxError
from django.template.base import Parser, Token, kwarg_re
from django.template.defaulttags import URLNode

from debusine.db.context import context
from debusine.server.scopes import urlconf_scope
from debusine.web.urls.url_utils import make_absolute_webui

register = template.Library()


class DebusineURLNode(URLNode):
    """Extend URLNode to generate URLs to the main Debusine web UI."""

    @override
    def render(self, ctx: Context) -> str:
        with urlconf_scope(context.require_scope().name):
            path = super().render(ctx)
            if self.asvar:
                ctx[self.asvar] = make_absolute_webui(ctx[self.asvar])
                return path
            else:
                return make_absolute_webui(path)


@register.tag
def debusine_url(parser: Parser, token: Token) -> DebusineURLNode:
    """Behave like the ``{% url %}`` tag, but link to the main web UI."""
    # This is copied from Django's template.defaulttags.url, except for the
    # node class used at the end. It needs to be kept in sync if new versions
    # of Django change the behaviour or the implementation of {% url %}
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "'%s' takes at least one argument, a URL pattern name." % bits[0]
        )
    viewname = parser.compile_filter(bits[1])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == "as":
        asvar = bits[-1]
        bits = bits[:-2]

    for bit in bits:
        match = kwarg_re.match(bit)
        if not match:
            raise TemplateSyntaxError("Malformed arguments to url tag")
        name, value = match.groups()
        if name:
            kwargs[name] = parser.compile_filter(value)
        else:
            args.append(parser.compile_filter(value))

    return DebusineURLNode(viewname, args, kwargs, asvar)
