"""
Security Validation for CLI
---------------------------
This module provides security validation functions to prevent insecure patterns
from being generated by the CLI scaffolding tools.
"""

# Dangerous field names that should not be allowed in user-generated models
DANGEROUS_FIELD_NAMES = {
    "is_superuser",
    "is_admin",
    "is_staff",
    "is_staff_user",
    "is_administrator",
    "has_admin_access",
    "admin",
    "superuser",
    "super_user",
    "root",
    "password_hash",
    "hashed_password",  # Should use framework's password security
    "secret_key",
    "api_key",
    "access_token",
    "refresh_token",
    "token",
}

# Dangerous resource names that should not be allowed
DANGEROUS_RESOURCE_NAMES = {
    "user",
    "admin",
    "adminuser",
    "admin_user",
    "superuser",
    "permission",
    "role",
    "token",
    "auth",
    "security",
}

# Reserved module paths that should not be used
RESERVED_MODULE_PATHS = {
    "swx_core.models",
    "swx_core.auth",
    "swx_core.security",
    "swx_core.rbac",
}


def validate_field_name(field_name: str) -> tuple[bool, str | None]:
    """
    Validates that a field name is not dangerous or reserved.

    Args:
        field_name: The field name to validate.

    Returns:
        tuple[bool, str | None]: (is_valid, error_message)
    """
    field_lower = field_name.lower().strip()

    # Check for dangerous field names
    if field_lower in DANGEROUS_FIELD_NAMES:
        return False, f"Field name '{field_name}' is reserved for security reasons. Use a different name."

    # Check for patterns that suggest privilege escalation
    if field_lower.startswith("is_") and any(
        keyword in field_lower for keyword in ["admin", "super", "staff", "root"]
    ):
        return False, f"Field name '{field_name}' suggests privilege escalation. Use RBAC permissions instead."

    # Check for password-related fields (should use framework's password security)
    if "password" in field_lower and field_lower != "password":
        return False, f"Field name '{field_name}' suggests password handling. Use framework's password security utilities."

    # Check for token-related fields
    if "token" in field_lower or "secret" in field_lower or "key" in field_lower:
        return False, f"Field name '{field_name}' suggests sensitive data. Use framework's security utilities."

    return True, None


def validate_resource_name(resource_name: str) -> tuple[bool, str | None]:
    """
    Validates that a resource name is not dangerous or reserved.

    Args:
        resource_name: The resource name to validate.

    Returns:
        tuple[bool, str | None]: (is_valid, error_message)
    """
    resource_lower = resource_name.lower().strip()

    # Check for dangerous resource names
    if resource_lower in DANGEROUS_RESOURCE_NAMES:
        return False, f"Resource name '{resource_name}' is reserved. Use a different name."

    # Check for patterns that suggest security-related resources
    if resource_lower in ["auth", "security", "rbac", "permission", "role"]:
        return False, f"Resource name '{resource_name}' conflicts with framework security modules. Use a different name."

    return True, None


def validate_module_path(module_path: str) -> tuple[bool, str | None]:
    """
    Validates that a module path is not reserved.

    Args:
        module_path: The module path to validate.

    Returns:
        tuple[bool, str | None]: (is_valid, error_message)
    """
    if module_path in RESERVED_MODULE_PATHS:
        return False, f"Module path '{module_path}' is reserved for framework use. Use 'swx_app.models' or your own app namespace."

    # Check if trying to create in swx_core
    if module_path.startswith("swx_core."):
        return False, f"Module path '{module_path}' is in framework code. Use 'swx_app.models' or your own app namespace."

    return True, None


def validate_columns(columns: list[tuple[str, str]]) -> tuple[bool, str | None]:
    """
    Validates all column names in a list.

    Args:
        columns: List of (field_name, field_type) tuples.

    Returns:
        tuple[bool, str | None]: (is_valid, error_message)
    """
    for field_name, _ in columns:
        is_valid, error = validate_field_name(field_name)
        if not is_valid:
            return False, error
    return True, None
