"""
core/dir_scan.py — VaultHound v1.0.0
Recursive directory scanner.
"""

from __future__ import annotations

from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path

from core.scanner import Scanner
from utils.helpers import should_scan_file, SKIP_DIRS
from utils.logger import safe_print, log
from utils.models import SecretFinding


def scan_directory(
    target_dir:   str,
    scanner:      Scanner,
    threads:      int = 10,
) -> tuple[list[SecretFinding], list[str]]:
    """
    Recursively scan a directory for secrets.

    Returns:
        (findings, files_scanned)
    """
    root = Path(target_dir)
    if not root.exists():
        safe_print(f"[danger]Directory not found: {target_dir}[/]")
        return [], []

    # Collect all scannable files
    files: list[Path] = []
    for path in root.rglob("*"):
        if path.is_file():
            # Skip hidden dirs
            if any(part in SKIP_DIRS for part in path.parts):
                continue
            if should_scan_file(path):
                files.append(path)

    safe_print(f"[info]  Scanning {len(files)} files in {target_dir}...[/]")

    all_findings: list[SecretFinding] = []
    scanned:      list[str]           = []
    errors:       list[str]           = []

    with ThreadPoolExecutor(max_workers=threads) as ex:
        futures = {ex.submit(scanner.scan_file, f): f for f in files}
        for fut in as_completed(futures):
            path = futures[fut]
            try:
                findings = fut.result()
                scanned.append(str(path))
                if findings:
                    all_findings.extend(findings)
                    safe_print(
                        f"  [danger]✘ {len(findings)} secret(s)[/] in "
                        f"[dim]{path}[/]"
                    )
            except Exception as e:
                errors.append(f"{path}: {e}")
                log.warning(f"Scan error {path}: {e}")

    return all_findings, scanned
