"""Test file path resolution utilities."""

from __future__ import annotations

import os
import re
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from pathlib import Path

_PARAMETERIZED_INDEX_RE = re.compile(r"\[(\d+)")


def extract_parameterized_test_index(test_name: str) -> int:
    """Extract the numeric index from a parameterized test name.

    Handles formats like ``test[ 0 ]``, ``test[1]``, and
    ``test[1] input=foo, expected=bar``.  Returns 1 when no numeric index is found.
    """
    m = _PARAMETERIZED_INDEX_RE.search(test_name)
    return int(m.group(1)) if m else 1


def file_path_from_module_name(
    module_name: str,
    project_root_path: Path,
) -> Path:
    """Convert a dotted module path to a file path."""
    return project_root_path / (module_name.replace(".", os.sep) + ".py")


def file_name_from_test_module_name(
    test_module_name: str,
    base_dir: Path,
) -> Path | None:
    """Resolve a test module name to a file path.

    Progressively strips trailing components until a
    match is found.
    """
    partial = test_module_name
    while partial:
        test_path = file_path_from_module_name(partial, base_dir)
        if test_path.exists():
            return test_path
        partial = ".".join(partial.split(".")[:-1])
    return None


def resolve_test_file_from_class_path(
    test_class_path: str,
    base_dir: Path,
) -> Path | None:
    """Resolve test file from pytest's test class path."""
    test_file_path = file_name_from_test_module_name(test_class_path, base_dir)

    # Strip last component (likely class name)
    if test_file_path is None and "." in test_class_path:
        module_without_class = ".".join(
            test_class_path.split(".")[:-1],
        )
        test_file_path = file_name_from_test_module_name(
            module_without_class, base_dir
        )

    # Progressively strip prefix components
    if test_file_path is None:
        parts = test_class_path.split(".")
        for num_to_strip in range(1, len(parts)):
            remaining = ".".join(parts[num_to_strip:])
            test_file_path = file_name_from_test_module_name(
                remaining, base_dir
            )
            if test_file_path:
                break
            if "." in remaining:
                remaining_no_class = ".".join(
                    remaining.split(".")[:-1],
                )
                test_file_path = file_name_from_test_module_name(
                    remaining_no_class, base_dir
                )
                if test_file_path:
                    break
    return test_file_path
