"""
utils/helpers.py — VaultHound v1.0.0
Utility functions.
"""

from __future__ import annotations

import re
from datetime import datetime
from pathlib import Path


def timestamp() -> str:
    return datetime.now().strftime("%Y%m%d_%H%M%S")


def ensure_dir(path: Path) -> Path:
    path.mkdir(parents=True, exist_ok=True)
    return path


def sanitize_dirname(name: str) -> str:
    return re.sub(r"[^\w\-.]", "_", name)[:80]


# File extensions to scan in DIR mode
SCANNABLE_EXTENSIONS = {
    ".py", ".js", ".ts", ".jsx", ".tsx",
    ".env", ".cfg", ".conf", ".config", ".ini",
    ".json", ".yaml", ".yml", ".toml",
    ".xml", ".properties",
    ".sh", ".bash", ".zsh", ".fish",
    ".rb", ".go", ".java", ".php", ".cs",
    ".tf", ".tfvars",          # Terraform
    ".dockerfile", ".docker",
    ".sql",
    ".txt", ".md", ".log",
    "",                        # no extension — e.g. Dockerfile, Makefile
}

# Extensions to always skip
SKIP_EXTENSIONS = {
    ".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico", ".webp",
    ".woff", ".woff2", ".ttf", ".eot", ".otf",
    ".pdf", ".zip", ".tar", ".gz", ".bz2", ".xz", ".7z",
    ".mp4", ".mp3", ".avi", ".mov", ".wav",
    ".pyc", ".pyo", ".class", ".o", ".so", ".dll", ".exe",
    ".min.js",  # minified JS — too noisy
}

# Directories to skip
SKIP_DIRS = {
    ".git", "node_modules", "__pycache__", ".tox", "venv", ".venv",
    "env", "dist", "build", ".next", ".nuxt",
    "vendor", "bower_components", ".idea", ".vscode",
}


def should_scan_file(path: Path) -> bool:
    """Return True if this file should be scanned."""
    name   = path.name
    suffix = path.suffix.lower()

    # Explicitly allow high-value dotfiles
    DOTFILE_WHITELIST = {
        ".env", ".env.local", ".env.production", ".env.staging",
        ".env.development", ".env.backup", ".env.test",
        ".bashrc", ".zshrc", ".bash_profile", ".profile",
        ".netrc", ".pgpass", ".npmrc", ".pypirc",
    }
    if name in DOTFILE_WHITELIST:
        return True

    # Skip other hidden files/dirs
    if name.startswith("."):
        return False

    if suffix in SKIP_EXTENSIONS:
        return False
    if suffix in SCANNABLE_EXTENSIONS:
        return True

    # Scan files with no extension (Makefile, Dockerfile etc)
    return suffix == ""


def redact(value: str) -> str:
    """Partially redact a secret value for safe display."""
    if len(value) <= 8:
        return value[:2] + "****"
    return value[:6] + "****" + value[-2:]
