"""
template — One-Shot YAML Template Generator.

Wandelt den inferierten k-ORE/SORE/CHARE regulären Ausdruck zurück
in ein menschenlesbares YAML-Skelett für LLM-Prompts.

Der Generator erzeugt:
  - Ein YAML-Grundgerüst mit Platzhaltern
  - Kommentare mit Kardinalitätshinweisen:
    * # PFLICHT: Genau 1 mal erforderlich
    * # PFLICHT: 1 oder mehrmals erforderlich
    * # OPTIONAL: 0 oder 1 mal (darf weggelassen werden)
    * # OPTIONAL: 0 oder mehrmals
    * # WAHLWEISE: alternatives Modul
"""


def parse_expression(expr):
    """Zerlegt einen regulären Ausdruck in seine Bestandteile."""
    if not expr or expr in ('∅', 'ε', ''):
        return [('empty', 'ε')]

    tokens = []
    i = 0
    while i < len(expr):
        if expr[i] == '(':
            depth = 1
            j = i + 1
            while j < len(expr) and depth > 0:
                if expr[j] == '(':
                    depth += 1
                elif expr[j] == ')':
                    depth -= 1
                j += 1
            group = expr[i:j]
            quantifier = ''
            if j < len(expr) and expr[j] in '*+?':
                quantifier = expr[j]
                j += 1
            tokens.append(('group', group, quantifier))
            i = j
        elif expr[i] == '|':
            tokens.append(('pipe', '|'))
            i += 1
        elif expr[i] == '.':
            if i + 1 < len(expr) and expr[i + 1] == '.':
                tokens.append(('concat', '..'))
                i += 2
            else:
                tokens.append(('concat', '.'))
                i += 1
        elif expr[i] in '*+?':
            if tokens and tokens[-1][0] == 'name':
                name, val, _ = tokens[-1]
                tokens[-1] = (name, val, expr[i])
            i += 1
        elif expr[i].isalnum() or expr[i] in '/_-':
            j = i
            while j < len(expr) and (expr[j].isalnum() or expr[j] in '/_-'):
                j += 1
            name = expr[i:j]
            tokens.append(('name', name, ''))
            i = j
        else:
            i += 1

    return tokens


def format_prompt_cardinality(quantifier):
    """Gibt die deutsche Kardinalitätsbeschreibung für einen Quantifier zurück."""
    mapping = {
        '': '# PFLICHT: Genau 1 mal erforderlich',
        '+': '# PFLICHT: 1 oder mehrmals erforderlich',
        '*': '# OPTIONAL: 0 oder mehrmals',
        '?': '# OPTIONAL: 0 oder 1 mal (darf weggelassen werden)',
    }
    return mapping.get(quantifier, '')


def generate_template(expr, context_key=None, include_header=True):
    """
    Generiert ein YAML-One-Shot-Template aus einem regulären Ausdruck.

    Args:
        expr: Der inferierte Ausdruck (String)
        context_key: Name des YAML-Container-Keys (z.B. 'tasks')
        include_header: Ob der Header-Teil (name, hosts) eingefügt wird

    Returns:
        String: YAML-Skelett mit Platzhaltern und Kardinalitätskommentaren
    """
    if not expr or expr in ('∅', 'ε'):
        return "# Keine Struktur inferiert (leere Sequenzen oder keine Beispiele)"

    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 = "    "

    tokens = parse_expression(expr)
    task_index = 0
    skip_until_pipe = False

    alternatives = []
    in_alternatives = False

    i = 0
    while i < len(tokens):
        token = tokens[i]

        if token[0] == 'group':
            group_str = token[1]
            quantifier = token[2]
            card = format_prompt_cardinality(quantifier)
            inner_expr = group_str[1:-1]
            if '|' in inner_expr:
                alts = inner_expr.split('|')
                lines.append(f"{indent}# WAHLWEISE (eines auswählen):")
                for alt in alts:
                    alt_clean = alt.strip()
                    lines.append(f"{indent}#   - {alt_clean}: <Parameter für {alt_clean}>")
                if card:
                    lines[-1] = f"{lines[-1]} {card}"
            else:
                lines.append(f"{indent}- {inner_expr}: <Parameter für {inner_expr}> {card}")
            task_index += 1

        elif token[0] == 'name':
            name = token[1]
            quantifier = token[2]
            card = format_prompt_cardinality(quantifier)
            lines.append(f"{indent}- {name}: <Parameter für {name}> {card}")
            task_index += 1

        elif token[0] == 'pipe':
            pass

        i += 1

    return '\n'.join(lines) + '\n'
