from pygitweb.actions import blog_link_spec, project_board_link
from pygitweb.templates_env import env, html_format, html_join, html_link, render_page, trusted_html


def test_table_escapes_plain_text() -> None:
    html = env.get_template("table.html").render(
        cols=["Name"],
        rows=[["<script>alert(1)</script>"]],
    )
    assert "<script>" not in html
    assert "&lt;script&gt;alert(1)&lt;/script&gt;" in html


def test_table_renders_link_without_double_escaping() -> None:
    cell = html_link("/p?a=commit&h=abc", "a<b", id="commit-link")
    html = env.get_template("table.html").render(cols=["Commit"], rows=[[cell]])
    assert 'href="/p?a=commit&amp;h=abc"' in html
    assert 'id="commit-link"' in html
    assert ">a&lt;b</a>" in html
    assert "&amp;amp;" not in html


def test_html_join_escapes_text_and_keeps_markup() -> None:
    joined = html_join([html_link("/a", "x"), " <", "a&b", ">"])
    assert str(joined) == '<a href="/a">x</a> &lt;a&amp;b&gt;'


def test_trusted_html_is_not_escaped_in_table() -> None:
    html = env.get_template("table.html").render(
        cols=["V"],
        rows=[[trusted_html("<em>ok</em>")]],
    )
    assert "<em>ok</em>" in html


def test_html_format_escapes_values() -> None:
    assert str(html_format("<pre>{}</pre>", "<hi>")) == "<pre>&lt;hi&gt;</pre>"


def test_render_page_uses_base_template_and_escapes_text() -> None:
    resp = render_page("message.html", title="Hello <x>", paragraphs=["Hi <there>"])
    text = resp.body.decode()
    assert text.startswith("<!DOCTYPE html>")
    assert "<title>Hello &lt;x&gt;</title>" in text
    assert "Hi &lt;there&gt;" in text
    assert text.count('<div class="page">') == 1
    assert "</body></html>" in text
    assert text.index('<div class="container-xl">') < text.index("Hi &lt;there&gt;")
    assert text.index("Hi &lt;there&gt;") < text.index("</body></html>")


def test_project_list_template_emits_links() -> None:
    resp = render_page(
        "project_list.html",
        title="Projects",
        notice=None,
        projects=[
            {
                "href": "/project/a<b",
                "path": "a<b",
                "descr": "d&d",
                "board_href": "/board/create?project=a%3Cb",
                "board_text": "create board",
                "board_style": None,
            }
        ],
    )
    text = resp.body.decode()
    assert 'href="/project/a&lt;b"' in text
    assert ">a&lt;b</a>" in text
    assert "d&amp;d" in text
    assert ">create board</a>" in text
    assert 'href="/board/create?project=a%3Cb"' in text
    assert "bg-secondary-lt" in text


def test_project_board_link_points_at_existing_board(monkeypatch) -> None:
    monkeypatch.setattr(
        "pygitweb.actions.git_get_references",
        lambda _project, _prefix: [("Tasks", "refs/tags/boards/Tasks")],
    )
    assert str(project_board_link("demo")) == '<a href="/project/demo/board/">project board</a>'


def test_project_board_link_offers_create_when_missing(monkeypatch) -> None:
    monkeypatch.setattr("pygitweb.actions.git_get_references", lambda _project, _prefix: [])
    monkeypatch.setattr("pygitweb.actions.settings.AUTH", True)
    html = str(project_board_link("my proj"))
    assert 'href="/board/create?project=my%20proj"' in html
    assert 'style="color: #999; cursor: not-allowed;"' in html
    assert ">create board</a>" in html

    monkeypatch.setattr("pygitweb.actions.settings.AUTH", False)
    plain = str(project_board_link("my proj"))
    assert "style=" not in plain
    assert ">create board</a>" in plain


def test_blog_link_spec_points_at_existing_blog(monkeypatch) -> None:
    monkeypatch.setattr("pygitweb.actions.project_has_blog", lambda _project: True)
    spec = blog_link_spec("demo")
    assert spec == {
        "href": "/project/demo/blog/",
        "text": "view blog",
        "style": None,
    }


def test_blog_link_spec_muted_when_missing(monkeypatch) -> None:
    monkeypatch.setattr("pygitweb.actions.project_has_blog", lambda _project: False)
    spec = blog_link_spec("my proj")
    assert spec == {
        "href": "#",
        "text": "no blog",
        "style": "color: #999; cursor: not-allowed;",
    }