"""Tests for Maintainability Index (Go)."""

from vibelexity.analyzers.go import analyze_source


def _mi(code: str) -> int | float:
    """Return MI of the first function in code."""
    result = analyze_source(code)
    assert result.functions, f"No functions found in:\n{code}"
    mi_val = result.functions[0].mi
    assert mi_val is not None
    return mi_val


# --- Trivial function (high MI) ---


def test_trivial_function():
    code = """
package main

func f() int {
    return 1
}
"""
    mi = _mi(code)
    assert mi > 50, f"Trivial function should have high MI, got {mi}"


def test_simple_add():
    code = """
package main

func add(a int, b int) int {
    return a + b
}
"""
    mi = _mi(code)
    assert mi > 50, f"Simple function should have high MI, got {mi}"


# --- Complex function (low MI) ---


def test_complex_function():
    code = """
package main

import "fmt"

func process(data []int, flag bool, mode bool, opt bool, extra bool) []int {
    result := make([]int, 0)
    total := 0
    count := 0
    for _, item := range data {
        if flag && mode {
            if item > 0 {
                for _, sub := range data {
                    if sub < 100 {
                        if opt || extra {
                            result = append(result, sub*2+total)
                            count += 1
                        } else {
                            result = append(result, sub-1)
                        }
                    } else if sub > 200 {
                        total += sub
                        count -= 1
                    }
                }
            } else if item < 0 {
                val := item
                if val > 0 && val < 50 {
                    result = append(result, val)
                } else if val >= 50 || val == 0 {
                    result = append(result, -val)
                }
            }
        } else if mode || opt {
            for _, sub := range data {
                if sub != item {
                    result = append(result, sub+item)
                    total += sub
                }
            }
        }
    }
    if count > 0 {
        return result[:count]
    }
    fmt.Println(total)
    return result
}
"""
    mi = _mi(code)
    assert mi < 50, f"Complex function should have low MI, got {mi}"


# --- Edge case: empty body ---


def test_empty_body():
    code = """
package main

func noop() {}
"""
    mi = _mi(code)
    assert mi > 50, f"Empty body function should have high MI, got {mi}"


# --- Edge case: no operators ---


def test_no_operators():
    code = """
package main

func f() {
    x := 1
    _ = x
}
"""
    mi = _mi(code)
    assert mi > 50, f"No-operator function should have high MI, got {mi}"


# --- MI is in valid range ---


def test_mi_range():
    code = """
package main

func f(x bool) int {
    if x {
        return 1
    }
    return 0
}
"""
    mi = _mi(code)
    assert 0 <= mi <= 100, f"MI should be in [0, 100], got {mi}"


# --- Multiple functions ---


def test_multiple_functions():
    code = """
package main

func simple() int {
    return 42
}

func moderate(x int, y int) int {
    if x > y {
        return x
    } else if x < y {
        return y
    } else {
        return x + y
    }
}
"""
    result = analyze_source(code)
    assert len(result.functions) == 2
    mi_simple = result.functions[0].mi
    mi_moderate = result.functions[1].mi
    assert mi_simple is not None and mi_moderate is not None
    assert mi_simple > mi_moderate, (
        f"Simple function should have higher MI: {mi_simple} vs {mi_moderate}"
    )
