import ast
from typing import Tuple
from typing import List
from typing import Any


def get_function_args(node: ast.FunctionDef) -> Tuple[List[Any], List[Any]]:
    """
    This functon will process function definition and will extract all
    arguments used by a given function and return all optional and non-optional
    args used by the function.

    Args:
        node: Function node containing function that needs to be analyzed

    Returns:
        (non_optional_args, optional_args): named function args
    """
    assert (
        type(node) == ast.FunctionDef
    ), "Incorrect node type. Expected ast.FunctionDef, got {}".format(type(node))
    total_args = len(node.args.args)
    default_args = len(node.args.defaults)

    optional_args = []
    non_optional_args = []
    # Handle positional args
    for i in range(total_args):
        if i + default_args < total_args:
            non_optional_args.append(node.args.args[i].arg)
        else:
            optional_args.append(node.args.args[i].arg)

    # Handle named args
    for arg in node.args.kwonlyargs:
        optional_args.append(arg.arg)

    return non_optional_args, optional_args