from __future__ import annotations

from pygitweb.static_tests.js_runtime import JsPage

_NAV = (
    '<div id="navbar-user">'
    '<a id="navbar-user-link" href="/login"></a>'
    '<span id="navbar-user-avatar" class="bg-secondary"></span>'
    '<div class="navbar-user-name"></div>'
    '<div class="navbar-user-meta"></div>'
    "</div>"
)


def test_missing_navbar_returns_immediately(js: JsPage) -> None:
    js.set_html("<div></div>")
    js.load("navbar-auth.js")
    assert js.count("#navbar-user") == 0


def test_missing_child_nodes_return_immediately(js: JsPage) -> None:
    js.set_html('<div id="navbar-user"></div>')
    js.load("navbar-auth.js")
    assert js.count(".navbar-user-name") == 0


def test_disabled_auth_renders_a_guest_who_cannot_sign_in(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": False})
    js.set_html(_NAV)
    js.load("navbar-auth.js")
    assert js.text(".navbar-user-name") == "Guest"
    assert js.text(".navbar-user-meta") == "Sign-in not used"
    assert js.attr("#navbar-user-link", "href") is None
    assert js.attr("#navbar-user-link", "aria-disabled") == "true"
    assert "pe-none" in js.classes("#navbar-user-link")


def test_admin_without_gravatar_uses_the_admin_avatar(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": True, "username": "Admin"})
    js.set_html(_NAV)
    js.load("navbar-auth.js")
    assert js.attr("#navbar-user", "data-logged-in") == "true"
    assert js.prop("#navbar-user-link", "href").endswith("/user")
    assert js.text(".navbar-user-name") == "Admin"
    assert js.text(".navbar-user-meta") == "Signed in"
    assert "bg-primary" in js.classes("#navbar-user-avatar")
    assert "svg" in js.prop("#navbar-user-avatar", "innerHTML")


def test_user_gravatar_falls_back_when_the_image_errors(js: JsPage) -> None:
    js.route(
        "/auth/status",
        body={"auth_enabled": True, "username": "ada", "gravatar_url": "http://img/a"},
    )
    js.set_html(_NAV)
    js.load("navbar-auth.js")
    assert js.prop("#navbar-user-avatar img", "src") == "http://img/a"
    js.run("document.querySelector('#navbar-user-avatar img').onerror()")
    assert js.count("#navbar-user-avatar img") == 0
    assert "bg-teal" in js.classes("#navbar-user-avatar")
    assert "bg-primary" not in js.classes("#navbar-user-avatar")


def test_signed_out_visitor_links_to_login(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": True, "username": ""})
    js.set_html(_NAV)
    js.load("navbar-auth.js")
    assert js.attr("#navbar-user", "data-logged-in") == "false"
    assert js.prop("#navbar-user-link", "href").endswith("/login")
    assert js.text(".navbar-user-meta") == "Not signed in"
    assert "bg-secondary" in js.classes("#navbar-user-avatar")


def test_signed_in_user_gets_profile_and_sign_out(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": True, "username": "ada"})
    js.set_html(
        '<div id="navbar-user">'
        '<a id="navbar-user-link" href="/login"></a>'
        '<span id="navbar-user-avatar" class="bg-secondary"></span>'
        '<div class="navbar-user-name"></div>'
        '<div class="navbar-user-meta"></div>'
        '<div id="navbar-user-menu" class="d-none">'
        '<a id="navbar-user-profile" href="/user"></a>'
        '<a id="navbar-user-logout" href="/logout"></a>'
        "</div></div>"
    )
    js.load("navbar-auth.js")
    assert "dropdown" in js.classes("#navbar-user")
    assert "dropup" in js.classes("#navbar-user")
    assert js.attr("#navbar-user-link", "data-bs-toggle") == "dropdown"
    assert js.prop("#navbar-user-profile", "href").endswith("/user")
    assert "next=/" in js.prop("#navbar-user-logout", "href")
    assert "d-none" not in js.classes("#navbar-user-menu")


def test_top_navbar_menu_opens_downward(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": True, "username": "ada"})
    js.set_html(
        '<div id="navbar-user" data-dropdown="down" data-login-href="/login?next=/project/demo/blog/">'
        '<a id="navbar-user-link" href="/login?next=/project/demo/blog/"></a>'
        '<span id="navbar-user-avatar" class="bg-secondary"></span>'
        '<div class="navbar-user-name"></div>'
        '<div class="navbar-user-meta"></div>'
        '<div id="navbar-user-menu" class="d-none"></div>'
        "</div>"
    )
    js.load("navbar-auth.js")
    assert "dropdown" in js.classes("#navbar-user")
    assert "dropup" not in js.classes("#navbar-user")


def test_signed_out_keeps_a_login_return_path(js: JsPage) -> None:
    js.route("/auth/status", body={"auth_enabled": True, "username": ""})
    js.set_html(
        '<div id="navbar-user" data-login-href="/login?next=/project/demo/blog/">'
        '<a id="navbar-user-link" href="/login"></a>'
        '<span id="navbar-user-avatar" class="bg-secondary"></span>'
        '<div class="navbar-user-name"></div>'
        '<div class="navbar-user-meta"></div>'
        "</div>"
    )
    js.load("navbar-auth.js")
    assert js.prop("#navbar-user-link", "href").endswith("/login?next=/project/demo/blog/")


def test_status_fetch_failure_sends_the_link_to_login(js: JsPage) -> None:
    js.route("/auth/status", error="offline")
    js.set_html(_NAV)
    js.load("navbar-auth.js")
    assert js.prop("#navbar-user-link", "href").endswith("/login")
    assert "bg-secondary" in js.classes("#navbar-user-avatar")