from typing import Sequence
from typing import Pattern
import re


def variable_ref_patterns(variable_name: str) -> Sequence[Pattern]:
    """
    Convert a variable name into a series of regular expressions that will
    match a reference to the variable. (Regular expression alternation syntax
    is too complicated and error-prone for this purpose.)

    Each regular expression matches one form of the variable syntax, and each
    regular expression has three groups:

    ---------------------------------------------------------------------------
    NOTE: This function is coupled to the `VariableSubstituter` class's
    grammar.
    ---------------------------------------------------------------------------

    Group 1 - The portion of the string that precedes the variable reference
    Group 2 - The variable reference
    Group 3 - The portion of the string those follows the variable reference

    For convenience, use the result with matches_variable_ref().

    :param variable_name: the variable name

    :return: The compiled regular expressions, as an iterable tuple
    """
    return (
        re.compile(r'^(.*)(\$\{' + variable_name + r'\})(.*)$'),
        re.compile(r'^(.*)(\$\{' + variable_name + r'\[\d*:?\d*\]\})(.*)$'),
        re.compile(r'^(.*)(\$' + variable_name + r')([^a-zA-Z_]+.*)$'),
        re.compile(r'^(.*)(\$' + variable_name + r')()$'), # empty group 3
        # This next bit of ugliness matches the ternary IF syntax
        re.compile(r'^(.*)(\${' + variable_name + r'\s*[=!]=\s*"[^}?:]*"\s*\?\s*"[^}?:]*"\s*:\s*"[^}?:]*"})(.*)$'),
        # And this one matches the edit syntax.
        re.compile(r'^(.*)(\${' + variable_name + '[/|][^/|]*[/|][^/|]*[/|][ig]?})(.*)$')
    )