from typing import Union
from typing import Callable
from typing import List
from typing import Tuple


def make_cmd(
    to_fn_call: Union[str, Callable[[List[str]], str]], arity: int
) -> Tuple[str, int]:
    """
    Returns a tuple with the transpiled command and its arity.

    :param to_fn_call
      If Callable, takes a list of variables that hold values popped from the
      stack (reversed) and returns a string representing a value created by
      running some function.
      If str, its format method will be called with the aforementioned list
      of variables as arguments.
    on those variables
    :param arity The arity of the function
    """
    var_names = [f"x{n}" for n in range(arity, 0, -1)]
    if isinstance(to_fn_call, str):
        if arity > 0:
            fn_call = to_fn_call.format(*var_names)
        else:
            fn_call = to_fn_call
    else:
        fn_call = to_fn_call(var_names)
    if arity > 0:
        cmd = f"{', '.join(var_names[::-1])} = pop(vy_globals.stack, {arity});"
    else:
        cmd = ""
    cmd += f"res = {fn_call}; vy_globals.stack.append(res);"
    return cmd, arity