"""Each test isolates one way a plausible-looking find_confusion is wrong: matching the prefix
as a substring instead of a true prefix, comparing names without PEP-503-style normalization,
and walking only the root's direct dependencies instead of the whole reachable graph."""
from sec_sbom import find_confusion


def _names(findings):
    return {f.name for f in findings}


def test_find_confusion_flags_direct_public_match_and_spares_private_only_name(
    sbom, internal_prefixes, public_index
):
    findings = find_confusion(sbom, internal_prefixes, public_index)
    names = _names(findings)

    assert "mycorp-auth" in names, (
        f"mycorp-auth starts with the internal prefix and is on the public index at "
        f"{public_index['mycorp-auth']} — it must be flagged; findings were {sorted(names)}"
    )
    assert "mycorp-internal-tool" not in names, (
        "mycorp-internal-tool starts with the internal prefix but nobody has published that name "
        f"publicly — it is not yet a confusion risk; findings were {sorted(names)}"
    )
    auth = next(f for f in findings if f.name == "mycorp-auth")
    assert auth.public_versions == ("0.1.0",), (
        f"mycorp-auth's finding must carry the public index's published versions, got {auth.public_versions!r}"
    )


def test_find_confusion_ignores_name_that_merely_contains_the_prefix(
    sbom, internal_prefixes, public_index
):
    findings = find_confusion(sbom, internal_prefixes, public_index)
    names = _names(findings)

    assert "django-mycorp-plugin" not in names, (
        "django-mycorp-plugin is public but its normalized name does not START WITH 'mycorp' — "
        "the prefix only appears in the middle of an unrelated public package's name, so a true "
        f"prefix match (not a substring search) must not flag it; findings were {sorted(names)}"
    )


def test_find_confusion_normalizes_case_and_separators_before_matching(
    sbom, internal_prefixes, public_index
):
    findings = find_confusion(sbom, internal_prefixes, public_index)
    names = _names(findings)

    assert "MyCorp_Telemetry" in names, (
        "MyCorp_Telemetry normalizes to mycorp-telemetry — same casing and separator rules PyPI "
        "and npm apply — which starts with the internal prefix and is on the public index at "
        f"{public_index['mycorp-telemetry']}; findings were {sorted(names)}"
    )


def test_find_confusion_walks_the_full_dependency_graph_not_just_direct_children(
    sbom, internal_prefixes, public_index
):
    findings = find_confusion(sbom, internal_prefixes, public_index)
    names = _names(findings)

    assert "mycorp-billing" in names, (
        "mycorp-billing is not a direct dependency of the root — it is requests's dependency, two "
        "hops away — but it is still reachable, starts with the internal prefix, and is on the "
        f"public index at {public_index['mycorp-billing']}; findings were {sorted(names)}"
    )
