"""Auto-discover lint and format commands from the project environment.

Instead of relying on user configuration, we probe the project's virtualenv
(and then the global PATH) for known tools.  The first tool found wins.
"""

from __future__ import annotations

import logging
import os
import shutil

logger = logging.getLogger(__name__)

# Ordered by preference — first match wins.
_LINT_TOOLS = ["ruff", "flake8"]
_FORMAT_TOOLS = ["ruff", "black"]

_VENV_DIRS = [".venv", "venv", "env"]


def _find_tool(tool_name: str, project_root: str) -> str | None:
    """Return the path to *tool_name* if it exists in the venv or on PATH."""
    is_windows = os.name == "nt"
    scripts = "Scripts" if is_windows else "bin"
    exe = f"{tool_name}.exe" if is_windows else tool_name

    for venv in _VENV_DIRS:
        candidate = os.path.join(project_root, venv, scripts, exe)
        if os.path.isfile(candidate):
            return candidate

    return shutil.which(tool_name)


def discover_test_command(
    project_root: str, rel_test_path: str, pythonpath_prefix: str = ""
) -> str:
    """Return a pytest command using the project venv Python if available."""
    python = _find_tool("python", project_root) or "python"
    return (
        f"{pythonpath_prefix}{python} -m pytest {rel_test_path} "
        f"-v --tb=short --no-header --disable-warnings"
    )


def discover_lint_command(project_root: str, rel_test_path: str) -> str | None:
    """Return a lint command string, or ``None`` if no linter is found."""
    for tool in _LINT_TOOLS:
        tool_path = _find_tool(tool, project_root)
        if tool_path:
            if tool == "ruff":
                return f"{tool_path} check --fix {rel_test_path}"
            if tool == "flake8":
                return f"{tool_path} {rel_test_path}"
    return None


def discover_format_command(project_root: str, rel_test_path: str) -> str | None:
    """Return a format command string, or ``None`` if no formatter is found."""
    for tool in _FORMAT_TOOLS:
        tool_path = _find_tool(tool, project_root)
        if tool_path:
            if tool == "ruff":
                return f"{tool_path} format {rel_test_path}"
            if tool == "black":
                return f"{tool_path} {rel_test_path}"
    return None
