import re

IDENTIFIER_RE = re.compile(r"^[A-Za-z0-9_$.]+$")


PATH_COMPONENT_RE = re.compile(r"^[A-Za-z0-9_$.-]+$")


def safe_identifier(value: str, name: str = "identifier") -> str:
    if not value:
        raise ValueError(f"Empty {name} not allowed")
    if not IDENTIFIER_RE.match(value):
        raise ValueError(f"Invalid {name}: {value!r}")
    return value


def safe_path_component(value: str, name: str = "path_component") -> str:
    if not value:
        raise ValueError(f"Empty {name} not allowed")
    # Block exact . or ..
    if value in {".", ".."}:
        raise ValueError(f"Invalid {name}: {value!r} (directory traversal)")
    # Block path separators
    if "/" in value or "\\" in value:
        raise ValueError(f"Invalid {name}: {value!r} (path separator not allowed)")
    # Block .. anywhere in the string
    if ".." in value:
        raise ValueError(f"Invalid {name}: {value!r} (directory traversal)")
    # Standard identifier check
    if not PATH_COMPONENT_RE.match(value):
        raise ValueError(f"Invalid {name}: {value!r}")
    return value


# Pattern for safe filename characters
SAFE_FILENAME_RE = re.compile(r"[^A-Za-z0-9_.-]")


def safe_filename(value: str, default: str = "export") -> str:
    if not value:
        return default
    # Replace unsafe characters with underscore
    sanitized = SAFE_FILENAME_RE.sub("_", value)
    # Collapse multiple underscores
    sanitized = re.sub(r"_+", "_", sanitized)
    # Strip leading/trailing underscores
    sanitized = sanitized.strip("_")
    # Lowercase for consistency
    sanitized = sanitized.lower()
    # Fallback if empty after sanitization
    return sanitized if sanitized else default


def escape_sql_string(value: str) -> str:
    return value.replace("'", "''")
