"""
Snowflake SQL command processing module.

Handles command decoding, rendering, and splitting for Snowflake SQL execution.
"""

import base64
from typing import List, Dict
from jinja2 import Environment

from noetl.core.logger import setup_logger
from noetl.core.runtime import sql_split

logger = setup_logger(__name__, include_location=True)


def decode_base64_commands(task_config: Dict) -> str:
    """
    Decode base64 encoded SQL commands from task configuration.
    
    Supports both base64-encoded commands (command_b64/commands_b64) and plain text (command/commands).
    Priority: command_b64 > commands_b64 > command > commands
    
    Args:
        task_config: Task configuration dictionary
        
    Returns:
        Decoded SQL commands string
        
    Raises:
        ValueError: If no command field is found or decoding fails
    """
    # Try base64-encoded versions first (preferred for security)
    command_b64 = task_config.get('command_b64') or task_config.get('commands_b64')
    
    if command_b64:
        try:
            decoded = base64.b64decode(command_b64).decode('utf-8')
            logger.debug(f"Decoded {len(decoded)} characters of SQL commands from base64")
            return decoded
        except Exception as e:
            logger.error(f"Failed to decode base64 commands: {e}")
            raise ValueError(f"Failed to decode base64 SQL commands: {e}")
    
    # Fallback to plain text commands (for convenience, like Postgres plugin)
    command_plain = task_config.get('command') or task_config.get('commands')
    
    if command_plain:
        logger.debug(f"Using plain text SQL commands ({len(command_plain)} characters)")
        return command_plain
    
    # No command found
    raise ValueError("No SQL command field found. Use 'command_b64'/'commands_b64' (base64) or 'command'/'commands' (plain text)")


def escape_task_with_params(task_with: Dict) -> Dict:
    """
    Escape special characters in task_with parameters for SQL compatibility.
    
    This prevents SQL injection and syntax errors when parameters are used
    in SQL statements.
    
    Args:
        task_with: Task 'with' parameters dictionary
        
    Returns:
        Dictionary with escaped parameter values
    """
    escaped = {}
    for key, value in (task_with or {}).items():
        if isinstance(value, str):
            # Escape single quotes by doubling them (SQL standard)
            escaped[key] = value.replace("'", "''")
        else:
            escaped[key] = value
    return escaped


def render_and_split_commands(
    commands_str: str,
    jinja_env: Environment,
    context: Dict,
    task_with: Dict
) -> List[str]:
    """
    Render Jinja2 templates in SQL commands and split into individual statements.
    
    Args:
        commands_str: Raw SQL commands string (may contain Jinja2 templates)
        jinja_env: Jinja2 environment for rendering
        context: Execution context for template rendering
        task_with: Task 'with' parameters to merge into context
        
    Returns:
        List of individual SQL statements
    """
    # Merge context and task_with for rendering
    render_context = {**context, **(task_with or {})}
    
    # Render Jinja2 templates
    try:
        template = jinja_env.from_string(commands_str)
        rendered = template.render(render_context)
        logger.debug(f"Rendered SQL commands: {len(rendered)} characters")
    except Exception as e:
        logger.error(f"Failed to render SQL template: {e}")
        raise ValueError(f"Failed to render SQL template: {e}")
    
    # Split into individual statements
    statements = sql_split(rendered)
    
    # Filter out empty statements
    statements = [s.strip() for s in statements if s.strip()]
    
    logger.info(f"Split SQL into {len(statements)} statement(s)")
    return statements
