"""
Utility functions for template rendering with Jinja2 support.
"""

from pathlib import Path
from typing import Any

from jinja2 import (
    Environment,
    FileSystemLoader,
    StrictUndefined,
    TemplateSyntaxError,
    UndefinedError,
    meta,
)


def render_prompt_template(template_path: Path, instruction: str) -> str:
    """
    Render a prompt template with the given instruction.

    Args:
        template_path: Path to the Jinja2 template file
        instruction: The instruction text to render in the template

    Returns:
        Rendered prompt content as a string

    Raises:
        FileNotFoundError: If the template file doesn't exist
        ValueError: If the template doesn't include an "instruction" variable
    """
    if not template_path.exists():
        raise FileNotFoundError(f"Template file not found: {template_path}")

    template_content = template_path.read_text()

    # Check if the template actually uses the instruction variable
    # Use Jinja2's meta module to parse and find all undefined variables
    env_for_parsing = Environment()
    try:
        ast = env_for_parsing.parse(template_content)
        undeclared_variables = meta.find_undeclared_variables(ast)

        if "instruction" not in undeclared_variables:
            raise ValueError(
                f"Prompt template {template_path} must include an 'instruction' "
                f"variable. Use {{{{ instruction }}}} (jinja2 syntax) in your template."
            )
    except TemplateSyntaxError:
        # Fallback to simple string check if parsing fails
        if (
            "{{ instruction }}" not in template_content
            and "{{instruction}}" not in template_content
        ):
            raise ValueError(
                f"Prompt template {template_path} must include an 'instruction' "
                f"variable. Use {{{{ instruction }}}} (jinja2 syntax) in your template."
            )

    try:
        # Use StrictUndefined to catch missing variables
        env = Environment(undefined=StrictUndefined)
        template = env.from_string(template_content)
        return template.render(instruction=instruction)
    except UndefinedError as e:
        # Missing variable error
        raise ValueError(
            f"Prompt template {template_path} has undefined variables. Error: {e}"
        ) from e
    except Exception as e:
        raise ValueError(f"Error rendering prompt template {template_path}: {e}") from e


def render_setup_script(template_path: Path, context: dict[str, Any]) -> str:
    """
    Render a setup script template with the given context.

    Args:
        template_path: Path to the Jinja2 template file
        context: Dictionary of variables to pass to the template

    Returns:
        Rendered script content as a string
    """
    if not template_path.exists():
        raise FileNotFoundError(f"Template file not found: {template_path}")

    # Create Jinja2 environment
    env = Environment(
        loader=FileSystemLoader(template_path.parent),
        trim_blocks=True,
        lstrip_blocks=True,
    )

    # Load and render template
    template = env.get_template(template_path.name)
    return template.render(**context)
