"""Tests for URL join utilities."""
from __future__ import annotations

from shared.utils import _join_url_parts, join_url, normalize_text, soup_of


# ---------------------------------------------------------------------------
# _join_url_parts
# ---------------------------------------------------------------------------

class TestJoinUrlParts:
    def test_empty_list(self):
        assert _join_url_parts([]) == ""

    def test_single_part(self):
        assert _join_url_parts(["hello"]) == "hello"

    def test_two_parts(self):
        assert _join_url_parts(["https://example.com", "path"]) == "https://example.com/path"

    def test_preserves_scheme(self):
        assert _join_url_parts(["https://example.com/", "/api/", "v1"]) == "https://example.com/api/v1"

    def test_trailing_slash_preserved(self):
        result = _join_url_parts(["https://example.com", "path/"])
        assert result.endswith("/")

    def test_no_trailing_slash_when_last_has_none(self):
        result = _join_url_parts(["https://example.com", "path"])
        assert not result.endswith("/")

    def test_strips_internal_slashes(self):
        result = _join_url_parts(["https://example.com/", "/api/", "/v1"])
        assert result == "https://example.com/api/v1"

    def test_absolute_url_mid_list_replaces(self):
        result = _join_url_parts(["https://old.com/foo", "https://new.com/bar"])
        assert result == "https://new.com/bar"

    def test_query_string_attached(self):
        result = _join_url_parts(["https://example.com/path", "?key=val"])
        assert result == "https://example.com/path?key=val"

    def test_fragment_attached(self):
        result = _join_url_parts(["https://example.com/path", "#section"])
        assert result == "https://example.com/path#section"

    def test_filters_none_and_empty(self):
        result = _join_url_parts(["https://example.com", None, "", "path"])
        assert result == "https://example.com/path"

    def test_no_scheme(self):
        result = _join_url_parts(["/foo", "bar", "baz/"])
        assert result == "foo/bar/baz/"

    def test_multiple_segments(self):
        result = _join_url_parts(["https://example.com", "a", "b", "c/"])
        assert result == "https://example.com/a/b/c/"


# ---------------------------------------------------------------------------
# join_url
# ---------------------------------------------------------------------------

class TestJoinUrl:
    def test_string_input(self):
        assert join_url("https://example.com") == "https://example.com"

    def test_list_input(self):
        assert join_url(["https://example.com", "path"]) == "https://example.com/path"

    def test_tuple_input(self):
        assert join_url(("https://example.com", "path/")) == "https://example.com/path/"


# ---------------------------------------------------------------------------
# normalize_text
# ---------------------------------------------------------------------------

class TestNormalizeText:
    def test_collapses_whitespace(self):
        assert normalize_text("  hello   world  ") == "hello world"

    def test_tabs_and_newlines(self):
        assert normalize_text("hello\t\nworld") == "hello world"

    def test_empty_string(self):
        assert normalize_text("") == ""

    def test_none_input(self):
        assert normalize_text(None) == ""

    def test_single_word(self):
        assert normalize_text("  word  ") == "word"


# ---------------------------------------------------------------------------
# soup_of
# ---------------------------------------------------------------------------

class TestSoupOf:
    def test_parses_html(self):
        s = soup_of("<p>Hello <b>world</b></p>")
        assert s.find("b").text == "world"

    def test_empty_html(self):
        s = soup_of("")
        assert s.text == ""
