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

"""Useful support code for Debusine views."""

from typing import Any

from django.utils.safestring import SafeString

import pygments
import pygments.formatters
import pygments.lexers

import yaml


class PaginationMixin:
    """Add elided_page_range in "context" via get_context_data()."""

    def get_context_data(self, *args, **kwargs):
        """Return super().get_context_data with elided_page_range."""
        context = super().get_context_data(*args, **kwargs)

        page_obj = context["page_obj"]
        context["elided_page_range"] = page_obj.paginator.get_elided_page_range(
            page_obj.number
        )

        return context


class UIDumper(yaml.SafeDumper):
    """A YAML dumper that represents multi-line strings in the literal style."""

    def represent_scalar(self, tag, value, style=None):
        """Represent multi-line strings in the literal style."""
        if style is None and "\n" in value:
            style = "|"
        return super().represent_scalar(tag, value, style=style)


def format_yaml(data: Any) -> str:
    """Format YAML data as syntax highlighted HTML."""
    lexer = pygments.lexers.get_lexer_by_name("yaml")
    formatter = pygments.formatters.HtmlFormatter(
        cssclass="file_highlighted",
        linenos=False,
    )
    formatted = pygments.highlight(
        yaml.dump(data, Dumper=UIDumper), lexer, formatter
    )
    return SafeString(formatted)
