"""Tests for Go parameter counting in fatness metrics."""

from tree_sitter import Parser

from vibelexity.metrics.fatness.go import param_count
from vibelexity.parsers.go import GO_LANGUAGE, parse as parse_go


def test_zero_params():
    """Function with no parameters."""
    code = """
func foo() int {
    return 42
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 0


def test_single_param():
    """Function with single parameter."""
    code = """
func foo(x int) int {
    return x
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 1


def test_multiple_params():
    """Function with multiple parameters."""
    code = """
func foo(x int, y string, z bool) int {
    return 42
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 3


def test_variadic_param():
    """Function with variadic parameter."""
    code = """
func foo(x ...int) int {
    return 42
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 1


def test_mixed_params():
    """Function with regular and variadic parameters."""
    code = """
func foo(x int, y ...string) int {
    return 42
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 2


def test_method_with_receiver():
    """Method with receiver parameter."""
    code = """
func (s *Struct) foo(x int) int {
    return x
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "method_declaration":
            func_nodes.append(node)
    assert len(func_nodes) == 1
    assert param_count(func_nodes[0]) == 1


def test_no_parameters_node():
    """Function with no parameters clause."""
    code = """
func foo() {
    // do nothing
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert param_count(func_nodes[0]) == 0


def test_long_parameter_list():
    """Function with many parameters."""
    code = """
func foo(a int, b int, c int, d int, e int, f int, g int, h int, i int, j int) int {
    return 42
}
"""
    root = parse_go(code)
    func_nodes = []
    for node in root.children:
        if node.type == "function_declaration":
            func_nodes.append(node)
    assert param_count(func_nodes[0]) == 10
