import pytest

from test.stack.test_helpers import (
    find_symbol_nodes,
    resolve_symbol,
    setup_stack_resolution,
)


@pytest.mark.blends_test_group("functional")
def test_single_file_resolver_end_to_end_python() -> None:
    view, record = setup_stack_resolution("stack_graph_single_file.py")

    symbol_id = view.symbols.symbol_to_id.get("x")
    assert symbol_id is not None

    ref_nodes = find_symbol_nodes(view, symbol_id=symbol_id, is_definition=False)
    def_nodes = find_symbol_nodes(view, symbol_id=symbol_id, is_definition=True)

    assert len(ref_nodes) == 1
    assert len(def_nodes) == 1

    result = resolve_symbol(view, record, "x")
    assert result == [def_nodes[0]]


@pytest.mark.blends_test_group("functional")
def test_single_file_resolver_end_to_end_python_scopes() -> None:
    view, record = setup_stack_resolution("stack_graph_single_file_scopes.py")

    result_x = resolve_symbol(view, record, "x")
    assert len(result_x) == 1, "x should resolve to one definition"

    result_y = resolve_symbol(view, record, "y")
    assert len(result_y) == 1, "y should resolve to one definition"


@pytest.mark.blends_test_group("functional")
def test_single_file_resolver_nested_scopes() -> None:
    view, record = setup_stack_resolution("stack_graph_single_file_nested.py")

    result_x = resolve_symbol(view, record, "x")
    assert len(result_x) == 1, "x should resolve to one definition"

    result_y = resolve_symbol(view, record, "y")
    assert len(result_y) == 1, "y should resolve to one definition"

    result_z = resolve_symbol(view, record, "z")
    assert len(result_z) == 1, "z should resolve to one definition"


@pytest.mark.blends_test_group("functional")
def test_single_file_resolver_shadowing() -> None:
    view, record = setup_stack_resolution("stack_graph_single_file_complex.py")

    symbol_id = view.symbols.symbol_to_id.get("x")
    assert symbol_id is not None

    ref_nodes = find_symbol_nodes(view, symbol_id=symbol_id, is_definition=False)
    def_nodes = find_symbol_nodes(view, symbol_id=symbol_id, is_definition=True)

    assert len(ref_nodes) == 1
    assert len(def_nodes) == 2  # noqa: PLR2004

    result = resolve_symbol(view, record, "x")
    assert len(result) == 2, (  # noqa: PLR2004
        "Uniform precedence should return all same-scope defs of x"
    )

    result_y = resolve_symbol(view, record, "y")
    assert len(result_y) == 1, "y should resolve to one definition"
