"""
This type stub file was generated by pyright.
"""

from functools import lru_cache
from typing import TypeAlias

from mesonbuild.mparser import ArrayNode
from mesonbuild.mparser import AssignmentNode
from mesonbuild.mparser import BaseNode
from mesonbuild.mparser import CodeBlockNode
from mesonbuild.mparser import DictNode
from mesonbuild.mparser import ElementaryNode
from mesonbuild.mparser import ForeachClauseNode
from mesonbuild.mparser import FunctionNode
from mesonbuild.mparser import IdNode
from mesonbuild.mparser import MethodNode
from mesonbuild.mparser import NotNode
from mesonbuild.mparser import PlusAssignmentNode
from mesonbuild.mparser import UMinusNode

"""A query tool for meson.build files."""

SelectValue: TypeAlias = type[AssignmentNode | PlusAssignmentNode | NotNode | UMinusNode]
SelectItems: TypeAlias = type[ForeachClauseNode]
WhereValue: TypeAlias = type[ArrayNode | DictNode | MethodNode | FunctionNode]
WhereItems: TypeAlias = type[IdNode]

def load_ast(source_root: str) -> CodeBlockNode | None:
    """Load the :abbr:`AST (Abstract Syntax Tree)` from the root :file:`meson.build`.

    :param source_root: Directory containing a top-level :file:`meson.build`.
    :type source_root: str
    :return: The AST for a meson build definition if one is available OR None.
    :rtype: CodeBlockNode | None
    """

def project_metadata(ast: CodeBlockNode) -> tuple[str, str]:
    """Extract project metadata from :file:`meson.build`

    :param ast: The AST for a :file:`meson.build`.
    :type ast: CodeBlockNode
    :return: The project name and license identifier.
    :rtype: tuple[str, str]
    """

@lru_cache(typed=True)
def query_simple(
    ast: CodeBlockNode, select: SelectValue = ..., where: WhereValue = ...
) -> set[BaseNode]:
    """Run a simplistic query with no node filtering.

    :param ast: The AST for a :file:`meson.build`.
    :type ast: CodeBlockNode
    :param select: Select node type, defaults to AssignmentNode
    :type select: SelectValue, optional
    :param where: Where node type, defaults to ArrayNode
    :type where: WhereValue, optional
    :return: Set of all nodes matching the selector.
    :rtype: set[BaseNode]
    """

@lru_cache(typed=True)
def query_complex(
    ast: CodeBlockNode,
    select: SelectValue = ...,
    where: WhereValue = ...,
    get: type[ElementaryNode] = ...,
) -> set[str]:
    """Run a complex (filtered) query of build item values.

    :param ast: The AST for a :file:`meson.build`.
    :type ast: CodeBlockNode
    :param select: select type, defaults to AssignmentNode
    :type select: SelectValue, optional
    :param where: where type, defaults to ArrayNode
    :type where: WhereValue, optional
    :param get: get type, defaults to StringNode
    :type get: type[ElementaryNode], optional
    :return: A set of node values matching the selector
    :rtype: set[str]
    """

@lru_cache(typed=True)
def query_loop_assignments(
    ast: CodeBlockNode,
    select: SelectItems = ...,
    where: type[ElementaryNode] = ...,
    get: type[ElementaryNode] = ...,
) -> set[str]:
    """Get a set of selected array items (must be assigned to a variable).

    :param ast: The AST for a :file:`meson.build`.
    :type ast: CodeBlockNode
    :param select: Select node type, defaults to ForeachClauseNode
    :type select: SelectItems, optional
    :param where: Where node type, defaults to IdNode
    :type where: WhereItems, optional
    :param get: Query node type, defaults to StringNode
    :type get: type[ElementaryNode], optional
    :return: A set of query matches
    :rtype: set[str]
    """

@lru_cache(typed=True)
def find_var_suffix(ast: CodeBlockNode, var_suffix: str) -> set[str]:
    """Get a set of build items based on a variable name suffix.

    :param ast: The AST for a :file:`meson.build`.
    :type ast: CodeBlockNode
    :param var_suffix: The text to look for.
    :type var_suffix: str
    :return: A set of query matches
    :rtype: set[str] | None
    """

def query_build_value(source_root: str, query: str) -> bool | None:
    """Load a :file:`meson.build` project and check if a query exists in array assignments.

    :param source_root: The path to directory containing a :file:`meson.build`
    :type source_root: str
    :param query: The text to look for.
    :type query: str
    :return: True if a query match is found, False if not, and None if the
             :file:`meson.build` could not be loaded.
    :rtype: set[str] | None
    """

def get_items_by_suffix(source_root: str, query: str) -> set[str] | None:
    """Load a :file:`meson.build` project and return build items.

    :param source_root: The path to directory containing a :file:`meson.build`
    :type source_root: str
    :param query: The text to look for.
    :type query: str
    """
