"""Marking — Convert k-OA to SOA over Σ^(k) (Definition 4.4, arXiv 1004.2372)."""

from .soa import SOA
from .expr import strip_k


def mark_koa(G):
    """
    Mark a k-OA G as a SOA over Σ^(k).

    Process nodes in arbitrary order. For the i-th occurrence of label a,
    replace by a^(i) (represented as "a_i").

    Returns a SOA H over Σ^(k) such that L(G) = strip(L(H)).
    """
    H = SOA()
    H.src = G.src
    H.sink = G.sink
    H._succ = {n: set(succ) for n, succ in G._succ.items()}
    H._pred = {n: set(pred) for n, pred in G._pred.items()}
    H._label = {}
    H._next = G._next

    counts = {}
    for n in G._succ:
        lab = G._label.get(n)
        if lab and lab not in ('ε', '∅') and n not in (G.src, G.sink):
            sym = strip_k(lab)
            counts[sym] = counts.get(sym, 0) + 1
            H._label[n] = f"{sym}_{counts[sym]}"
        elif n in (G.src, G.sink):
            H._label[n] = None
        else:
            H._label[n] = lab

    return H


def strip_expression(expr):
    """Strip k-ORE markers from expression: a_i → a.

    Returns expression over original alphabet Σ.
    """
    import re
    result = re.sub(r'(_\d+)', '', expr)
    return result
