from backend.utils.addressMatch import AddressMatch


class TestNormaliseAddress:
    def test_lowercases_input(self):
        assert AddressMatch.normalise_address("1 HIGH STREET") == "1 high street"

    def test_expands_road_abbreviation(self):
        assert AddressMatch.normalise_address("1 Moreton Rd") == "1 moreton road"

    def test_expands_avenue_abbreviation(self):
        assert AddressMatch.normalise_address("2 Park Ave") == "2 park avenue"

    def test_removes_punctuation_keeps_slash(self):
        result = AddressMatch.normalise_address("Flat 1/A, Some Road")
        assert "," not in result
        assert "/" in result

    def test_splits_digit_letter_suffix(self):
        assert "42 a" in AddressMatch.normalise_address("42a Some Road")

    def test_empty_string_returns_empty(self):
        assert AddressMatch.normalise_address("") == ""

    def test_removes_no_prefix(self):
        result = AddressMatch.normalise_address("No 5 High Street")
        assert "no" not in result.split()
        assert "5" in result


class TestScore:
    def test_identical_address_scores_one(self):
        assert AddressMatch.score("1 High Street", "1 High Street") == 1.0

    def test_case_insensitive(self):
        assert AddressMatch.score("1 HIGH STREET", "1 high street") == 1.0

    def test_street_type_synonym_scores_one(self):
        # "Rd" expands to "road" during normalisation — should be identical
        assert AddressMatch.score("1 High Rd", "1 High Road") == 1.0

    def test_different_building_numbers_score_zero(self):
        assert AddressMatch.score("1 High Street", "2 High Street") == 0.0

    def test_disjoint_number_sets_score_zero(self):
        assert AddressMatch.score("1 High Street", "99 Nowhere Lane") == 0.0

    def test_user_address_has_number_but_epc_does_not_scores_zero(self):
        assert AddressMatch.score("1 High Street", "High Street") == 0.0

    def test_partial_address_scores_above_threshold(self):
        # Extra token in user address ("London") — same building number, high overlap
        score = AddressMatch.score("1 High Street London", "1 High Street")
        assert 0.6 <= score < 1.0

    def test_flat_number_mismatch_scores_zero(self):
        # User has two numbers but no "flat" token; EPC has different flat number
        # Triggers the order-sensitive flat guard
        score = AddressMatch.score("3 42 High Street", "Flat 7 42 High Street")
        assert score == 0.0
