import subprocess
import sys
from typing import Optional

import pytest

from azure_functions_doctor import target_resolver


def test_resolve_python_version() -> None:
    """Test resolving the current Python version."""
    result = target_resolver.resolve_target_value("python")
    assert result == sys.version.split()[0]


def test_resolve_func_core_tools_version(monkeypatch: pytest.MonkeyPatch) -> None:
    """Test resolving func_core_tools version via subprocess."""
    monkeypatch.setattr(
        "azure_functions_doctor.target_resolver.shutil.which", lambda name: "/usr/bin/func"
    )

    def mock_check_output(cmd: list[str], text: bool, timeout: Optional[int] = None) -> str:
        return "4.0.5198"

    monkeypatch.setattr(subprocess, "check_output", mock_check_output)
    result = target_resolver.resolve_target_value("func_core_tools")
    assert result == "4.0.5198"


def test_resolve_func_core_tools_fallback(monkeypatch: pytest.MonkeyPatch) -> None:
    """Test fallback when func_core_tools resolution fails."""
    monkeypatch.setattr(
        "azure_functions_doctor.target_resolver.shutil.which", lambda name: "/usr/bin/func"
    )

    def mock_check_output(cmd: list[str], text: bool, timeout: Optional[int] = None) -> str:
        raise Exception("not found")

    monkeypatch.setattr(subprocess, "check_output", mock_check_output)
    result = target_resolver.resolve_target_value("func_core_tools")
    assert result == "unknown_error"


def test_resolve_func_core_tools_not_installed_when_binary_missing(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    monkeypatch.setattr("azure_functions_doctor.target_resolver.shutil.which", lambda name: None)

    result = target_resolver.resolve_target_value("func_core_tools")

    assert result == "not_installed"


def test_resolve_func_core_tools_timeout_expired(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(
        "azure_functions_doctor.target_resolver.shutil.which", lambda name: "/usr/bin/func"
    )

    def mock_check_output(cmd: list[str], text: bool, timeout: Optional[int] = None) -> str:
        raise subprocess.TimeoutExpired(cmd, 10.0)

    monkeypatch.setattr(subprocess, "check_output", mock_check_output)
    result = target_resolver.resolve_target_value("func_core_tools")
    assert result == "timeout"


def test_resolve_func_core_tools_called_process_error(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(
        "azure_functions_doctor.target_resolver.shutil.which", lambda name: "/usr/bin/func"
    )

    def mock_check_output(cmd: list[str], text: bool, timeout: Optional[int] = None) -> str:
        raise subprocess.CalledProcessError(2, cmd)

    monkeypatch.setattr(subprocess, "check_output", mock_check_output)
    result = target_resolver.resolve_target_value("func_core_tools")
    assert result == "error_2"
