from __future__ import annotations

from revibe.core.autocompletion.fuzzy import fuzzy_match


def test_empty_pattern_matches_anything() -> None:
    result = fuzzy_match("", "any_text")

    assert result.matched is True
    assert result.score == 0.0
    assert result.matched_indices == ()


def test_matches_exact_prefix() -> None:
    result = fuzzy_match("src/", "src/main.py")

    assert result.matched_indices == (0, 1, 2, 3)


def test_no_match_when_characters_are_out_of_order() -> None:
    result = fuzzy_match("ms", "src/main.py")

    assert result.matched is False


def test_treats_consecutive_characters_as_subsequence() -> None:
    result = fuzzy_match("main", "src/main.py")

    assert result.matched_indices == (4, 5, 6, 7)


def test_ignores_case() -> None:
    result = fuzzy_match("SRC", "src/main.py")

    assert result.matched_indices == (0, 1, 2)


def test_treats_scattered_characters_as_subsequence() -> None:
    result = fuzzy_match("sm", "src/main.py")

    assert result.matched_indices == (0, 4)


def test_treats_path_separator_as_word_boundary() -> None:
    result = fuzzy_match("m", "src/main.py")

    assert result.matched_indices == (4,)


def test_prefers_word_boundary_matching_over_subsequence() -> None:
    boundary_result = fuzzy_match("ma", "src/main.py")
    subsequence_result = fuzzy_match("ma", "src/important.py")

    assert boundary_result.score > subsequence_result.score


def test_scores_exact_prefix_match_higher_than_consecutive_and_subsequence() -> None:
    prefix_result = fuzzy_match("src", "src/main.py")
    consecutive_result = fuzzy_match("main", "src/main.py")
    subsequence_result = fuzzy_match("sm", "src/main.py")

    assert prefix_result.matched_indices == (0, 1, 2)
    assert prefix_result.score > consecutive_result.score
    assert prefix_result.score > subsequence_result.score


def test_finds_no_match_when_pattern_is_longer_than_entry() -> None:
    result = fuzzy_match("very_long_pattern", "short")

    assert result.matched is False


def test_prefers_consecutive_match_over_subsequence() -> None:
    consecutive = fuzzy_match("main", "src/main.py")
    subsequence = fuzzy_match("mn", "src/main.py")

    assert consecutive.score > subsequence.score


def test_prefers_case_sensitive_match_over_case_insensitive() -> None:
    case_match = fuzzy_match("Main", "src/Main.py")
    case_insensitive_match = fuzzy_match("main", "src/Main.py")

    assert case_match.score > case_insensitive_match.score


def test_treats_uppercase_letter_as_word_boundary() -> None:
    result = fuzzy_match("MP", "src/MainPy.py")

    assert result.matched_indices == (4, 8)


def test_favors_earlier_positions() -> None:
    result = fuzzy_match("a", "banana")

    assert result.matched_indices == (1,)
