"""template — One-Shot YAML Template Generator from AST nodes."""

from .grammar import Symbol, Concat, Alt, Plus, Optional, Star, Epsilon, Empty


def format_cardinality(node):
    """Return cardinality description for an AST node."""
    if isinstance(node, Plus):
        return '# PFLICHT: 1 oder mehrmals erforderlich'
    if isinstance(node, Optional):
        return '# OPTIONAL: 0 oder 1 mal (darf weggelassen werden)'
    if isinstance(node, Star):
        return '# OPTIONAL: 0 oder mehrmals'
    return '# PFLICHT: Genau 1 mal erforderlich'


def generate_template(node, context_key=None, include_header=True):
    """Generate a YAML one-shot template from an AST node.

    Args:
        node: Grammar AST node
        context_key: YAML container key (e.g. 'tasks')
        include_header: Whether to include header section (name, hosts)

    Returns:
        YAML skeleton with placeholders and cardinality comments
    """
    if node is None or isinstance(node, Empty):
        return "# No structure inferred (empty sequences or no examples)"

    if include_header:
        lines = [
            "- name: <Name des Plays>",
            "  hosts: <Ziel-Server> # PFLICHT: Genau 1 mal erforderlich",
        ]
        if context_key:
            lines.append(f"  {context_key}:")
        else:
            lines.append("  tasks:")
        indent = "    "
    else:
        lines = []
        if context_key:
            lines.append(f"  {context_key}: # Container-Kontext: {context_key}")
        else:
            lines.append("  tasks:")
        indent = "    "

    _generate_node(node, lines, indent)
    return '\n'.join(lines) + '\n'


def _generate_node(node, lines, indent):
    """Recursively generate YAML lines from AST node."""
    if isinstance(node, Symbol):
        lines.append(f"{indent}- {node.value}: <params>")
    elif isinstance(node, Plus):
        card = format_cardinality(node)
        _generate_wrapped(node.child, lines, indent, card)
    elif isinstance(node, Optional):
        card = format_cardinality(node)
        _generate_wrapped(node.child, lines, indent, card)
    elif isinstance(node, Star):
        card = format_cardinality(node)
        _generate_wrapped(node.child, lines, indent, card)
    elif isinstance(node, Alt):
        lines.append(f"{indent}# CHOOSE (pick one):")
        for part in node.parts:
            name = _node_name(part)
            lines.append(f"{indent}#   - {name}: <params>")
    elif isinstance(node, Concat):
        for part in node.parts:
            _generate_node(part, lines, indent)
    elif isinstance(node, Epsilon):
        pass
    elif isinstance(node, Empty):
        pass


def _generate_wrapped(child, lines, indent, card):
    """Generate a child node with cardinality annotation."""
    if isinstance(child, Alt):
        lines.append(f"{indent}# CHOOSE (pick one):")
        for part in child.parts:
            name = _node_name(part)
            lines.append(f"{indent}#   - {name}: <params>")
        lines[-1] = f"{lines[-1]} {card}"
    elif isinstance(child, Symbol):
        lines.append(f"{indent}- {child.value}: <params> {card}")
    elif isinstance(child, Concat):
        for part in child.parts:
            _generate_node(part, lines, indent)
    else:
        _generate_node(child, lines, indent)


def _node_name(node):
    """Get a human-readable name for a node."""
    if isinstance(node, Symbol):
        return node.value
    if isinstance(node, Concat):
        return ".".join(_node_name(p) for p in node.parts)
    if isinstance(node, Alt):
        return "|".join(_node_name(p) for p in node.parts)
    return "..."
