"""State file discovery — recursively find .tfstate files.

Walks a directory tree, skipping hidden dirs and node_modules,
returns sorted paths up to a configurable limit.
"""

from __future__ import annotations

import re
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from pathlib import Path

from complyform.core.errors import (
    DiscoverNoStatesFoundError,
    DiscoverTooManyStatesError,
)

_SKIP_DIRS = frozenset({"node_modules"})
_MIN_FILE_BYTES = 2


def discover_state_files(
    directory: Path,
    pattern: str = "*.tfstate",
    limit: int = 50,
) -> list[Path]:
    """Recursively discover state files matching glob pattern.

    Args:
        directory: Root directory to search.
        pattern: Glob pattern (default: *.tfstate).
        limit: Maximum files to return.

    Returns:
        Sorted list of Path objects.

    Raises:
        DiscoverNoStatesFoundError: Zero matches.
        DiscoverTooManyStatesError: Exceeds limit.
    """
    found: list[Path] = []
    for path in directory.rglob(pattern):
        if not path.is_file():
            continue
        # Skip hidden directories and node_modules
        if any(
            part.startswith(".") or part in _SKIP_DIRS
            for part in path.relative_to(directory).parts[:-1]
        ):
            continue
        # Skip tiny/corrupt files
        if path.stat().st_size < _MIN_FILE_BYTES:
            continue
        found.append(path)

    if not found:
        raise DiscoverNoStatesFoundError(str(directory), pattern)

    found.sort(key=lambda p: str(p))

    if len(found) > limit:
        raise DiscoverTooManyStatesError(len(found), limit, str(directory))

    return found


def derive_source_label(state_path: Path, base_directory: Path) -> str:
    """Derive source_state label from state file path relative to base.

    Replace path separators and dots with hyphens, strip leading
    hyphens, lowercase, remove .tfstate suffix.
    """
    try:
        rel = state_path.relative_to(base_directory)
    except ValueError:
        rel = state_path
    label = re.sub(r"[/\\.]", "-", str(rel))
    label = re.sub(r"-tfstate$", "", label)
    label = re.sub(r"-terraform$", "", label)
    label = label.strip("-").lower()
    return label
