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

import rich.repr
from abc import abstractmethod
from collections.abc import Generator
from dataclasses import dataclass
from typing import Generic, Literal, Self, TYPE_CHECKING, TypeVar
from tree_sitter import Node as TSNode
from graph_sitter.codebase.codebase_graph import CodebaseGraph
from graph_sitter.core.autocommit import commiter, reader, remover, writer
from graph_sitter.core.external_module import ExternalModule
from graph_sitter.core.interfaces.chainable import Chainable
from graph_sitter.core.interfaces.editable import Editable
from graph_sitter.core.interfaces.exportable import Exportable
from graph_sitter.core.interfaces.importable import Importable
from graph_sitter.core.interfaces.usable import Usable
from graph_sitter.core.node_id_factory import NodeId
from graph_sitter.core.statements.import_statement import ImportStatement
from graph_sitter.enums import ImportType, NodeType
from graph_sitter.writer_decorators import apidoc, noapidoc
from graph_visualization.enums import VizNode
from graph_sitter.core.file import SourceFile
from graph_sitter.core.symbol import Symbol

if TYPE_CHECKING:
    ...
TSourceFile = TypeVar("TSourceFile", bound="SourceFile")
@dataclass
class ImportResolution(Generic[TSourceFile]):
    """Represents the resolution of an import statement to a symbol defined in another file.

    Has the following properties:
    - from_file: Optional[SourceFile]. None when import resolves to an external module
    - symbol: Optional[Union[Symbol, ExternalModule]]. None when import resolves to an external module
    - imports_file: bool. True when we import the entire file (e.g. `from a.b.c import foo`)
    """
    from_file: TSourceFile | None = ...
    symbol: Symbol | ExternalModule | None = ...
    imports_file: bool = ...


TSourceFile = TypeVar("TSourceFile", bound="SourceFile")
@apidoc
class Import(Usable[ImportStatement], Chainable, Generic[TSourceFile]):
    """Represents a single symbol being imported.

    For example, this is one `Import` in Python (and similar applies to Typescript, etc.):
    ```
    from a.b import c
    ```

    This is two separate `Import` in Python:
    ```
    from a.b import c, d  # one import for each `c` and `d`
    ```
    Attributes:
        symbol_name: The name of the symbol being imported. For instance import a as b has a symbol_name of a.
        import_statement: the ImportStatement that this import belongs to
    """
    to_file_id: NodeId
    module: Editable | None
    symbol_name: Editable | None
    alias: Editable | None
    node_type: Literal[NodeType.IMPORT] = ...
    import_type: ImportType
    import_statement: ImportStatement
    def __init__(self, ts_node: TSNode, file_node_id: NodeId, G: CodebaseGraph, parent: ImportStatement, module_node: TSNode | None, name_node: TSNode | None, alias_node: TSNode | None, import_type: ImportType = ...) -> None:
        ...
    
    def __rich_repr__(self) -> rich.repr.Result:
        ...
    
    @noapidoc
    @abstractmethod
    def resolve_import(self, base_path: str | None = ...) -> ImportResolution[TSourceFile] | None:
        """Resolves the import to a symbol defined outside the file.

        Returns an ImportResolution object.
        """
        ...
    
    @noapidoc
    @commiter
    def add_symbol_resolution_edge(self) -> None:
        """Resolves the import to a symbol defined outside the file.

        If import is successfully resolved, a new edge is added to the graph. Must be called after
        `parse()` has been called for every file in the codebase. Returns the node id of the
        resolved import object.
        """
        ...
    
    @property
    @reader
    def name(self) -> str | None:
        """Returns the name or alias of the symbol being imported.

        Returns an identifier for the import which can be either the alias name of an imported symbol if it exists, or None.
        For example, in `from a.b import c as d`, this returns 'd'.
        For example, in `import { c as d } from 'a/b'`, this returns 'd'.

        Args:
            None

        Returns:
            str | None: The alias of the imported symbol if it exists, otherwise None.
        """
        ...
    
    @reader
    def is_aliased_import(self) -> bool:
        """Returns True if this import is aliased.

        Checks if the current import has an alias that is different from its original name.
        For example, in 'from foo import bar as baz', returns True because 'baz' is different from 'bar'.
        In 'from foo import bar', returns False because there is no alias.

        Args:
            None

        Returns:
            bool: True if the import has an alias different from its original name, False otherwise.
        """
        ...
    
    @abstractmethod
    def is_module_import(self) -> bool:
        """Returns True if this import is importing an entire module/file.

        Used to identify module imports vs symbol imports. This method evaluates whether
        the import is bringing in an entire module rather than specific symbols.

        Returns:
            bool: True if this import represents a module/file import, False if it represents a symbol import.
        """
        ...
    
    @reader
    def is_symbol_import(self) -> bool:
        """Returns True if this import is importing a symbol rather than a module.

        A symbol import is any import that references a specific object from a module, rather than importing the entire module. This method is the opposite of `is_module_import`.

        Returns:
            bool: True if this import is a symbol import, False if it is a module import.
        """
        ...
    
    @reader
    def is_wildcard_import(self) -> bool:
        """Returns True if the import symbol is a wildcard import.

        Determines whether this Import is a wildcard import, which means it imports all named exports from a module.
        Wildcard imports are represented using `*` in Python (e.g. `from module import *`)
        or `*` in TypeScript (e.g. `import * as name from 'module'`).

        Returns:
            bool: True if this is a wildcard import, False otherwise.
        """
        ...
    
    @property
    @abstractmethod
    def namespace(self) -> str | None:
        """Returns the namespace prefix that must be used with dot notation to reference the
        imported symbol.

        The namespace is the prefix required to access the imported symbol through dot notation.
        For example, in 'import foo as bar', bar is the namespace needed to access foo's exports as 'bar.xyz'.

        Returns:
            str | None: The namespace prefix if one exists, None otherwise.
                - For symbol imports or unnamed wildcard imports: None
                - For module imports: The module name or the module alias
        """
        ...
    
    @property
    @reader
    def from_file(self) -> TSourceFile | None:
        """Returns the SourceFile that an Import is importing from.

        This property traverses the Symbol edge to find the source file where the imported symbol is defined.

        Args:
            None

        Returns:
            TSourceFile | None: The SourceFile containing the imported symbol.
                Returns None if:
                - The import resolves to an external module
                - The imported symbol cannot be resolved
        """
        ...
    
    @property
    @reader
    def to_file(self) -> TSourceFile:
        """SourceFile that this import resides in.

        Returns the source file in which the current import statement is located. This property helps track the location
        and context of import statements within the codebase graph.

        Returns:
            TSourceFile: The source file containing this import statement.
        """
        ...
    
    @property
    @reader
    def resolved_symbol(self) -> Symbol | ExternalModule | TSourceFile | None:
        """Returns the symbol, source file, or external module that this import ultimately resolves
        to.

        This method follows indirect import chains to find the final resolved object. For example, if file A imports from B, which imports from C, this method returns the object from C.

        Returns:
            Symbol | ExternalModule | TSourceFile | None: The final resolved object that this import points to.
                - Symbol: If the import resolves to a symbol defined in the codebase
                - ExternalModule: If the import resolves to an external module
                - TSourceFile: If the import resolves to an entire source file
                - None: If the import cannot be resolved

        Note:
            If there is a circular import chain, returns the first repeated import in the chain.
        """
        ...
    
    @property
    @reader
    def imported_symbol(self) -> Symbol | ExternalModule | TSourceFile | Import | None:
        """Returns the symbol directly being imported, including an indirect import and an External
        Module.

        This property resolves the import's target and handles export-chain resolution. If the imported symbol
        is an export, this method will follow the export chain until it reaches the final target.

        Returns:
            Union[Symbol, ExternalModule, TSourceFile, Import, None]: The final resolved import target.
            Can be:
                - Symbol: The imported symbol
                - ExternalModule: If import resolves to an external module
                - SourceFile: If importing an entire file/module
                - Import: If there is a circular import
                - None: If the import is unresolved
        """
        ...
    
    @property
    @abstractmethod
    def imported_exports(self) -> list[Exportable]:
        """Returns the enumerated list of symbols imported from a module import.

        If the import represents a module/file import, returns a list of all exported symbols from that module.
        If the import is a symbol import, returns a list containing only the imported symbol.

        Returns:
            list[Exportable]: A list of exported symbols. For module imports, contains all exports from the module.
                For symbol imports, contains only the single imported symbol.
        """
        ...
    
    @writer
    def set_import_module(self, new_module: str) -> None:
        """Sets the module of an import.

        Updates the module of an import statement while maintaining the import symbol. For named imports, this changes the module path that follows 'from' or is wrapped in quotes.

        Args:
            new_module (str): The new module path to import from.

        Returns:
            None

        Note:
            If the import has no module (e.g., direct imports), this method has no effect.
        """
        ...
    
    @writer
    def set_import_symbol_alias(self, new_alias: str) -> None:
        """Sets alias or name of an import at the declaration level.

        Changes the name used to refer to an imported symbol at its import declaration, either by modifying the alias if one exists,
        or the name itself if no alias is used.The change only affects the import declaration, not import usages or callsites.

        Args:
            new_alias (str): The new name to use for the imported symbol.

        Returns:
            None
        """
        ...
    
    def rename(self, new_name: str, priority: int = ...) -> tuple[NodeId, NodeId]:
        """Renames the import symbol and updates all its usages throughout the codebase.

        Renames both the import symbol name and any usage references to match the new name. If the import is aliased, only changes the symbol name and not the alias.

        Args:
            new_name (str): The new name to give the imported symbol.
            priority (int, optional): Priority of the rename operation. Defaults to 0.

        Returns:
            tuple[NodeId, NodeId]: A tuple containing (file_node_id, new_import_node_id).

        Note:
            For an import like 'from a.b.c import d as e', renaming with 'XYZ' will result in:
            'from a.b.c import XYZ as e'

            For an import like 'import { d as e } from 'a/b/c'', renaming with 'XYZ' will result in:
            'import { XYZ as e } from 'a/b/c''
        """
        ...
    
    @remover
    def remove(self, delete_formatting: bool = ..., priority: int = ..., dedupe: bool = ...) -> None:
        """Remove this import from the import statement.

        If this import belongs to an import statement with multiple imports, removes just this single import from it.
        If this is the only import in the import statement, removes the entire import statement.

        Args:
            delete_formatting (bool, optional): Whether to delete any associated formatting. Defaults to True.
            priority (int, optional): The priority of the operation. Defaults to 0.
            dedupe (bool, optional): Whether to deduplicate imports. Defaults to True.

        Returns:
            None
        """
        ...
    
    @property
    @reader
    def import_specifier(self) -> Editable:
        """Returns the specific editable text representation of the import identifier within the
        import statement.

        Retrieves the import specifier text that appears in the actual import statement. This is the portion of text that identifies what is being imported.

        Returns:
            Editable: The editable text object representing the import specifier.
                For named imports like 'import { a as b } from 'c'', returns 'a as b'.
                For from imports like 'from a.b import c', returns 'c'.

        Raises:
            ValueError: If the subclass does not implement this property.
        """
        ...
    
    @reader
    def is_reexport(self) -> bool:
        """Returns true if the Import object is also an Export object.

        Checks whether this Import node has a corresponding Export node with the same source.
        If the import is an export, it implies there are no direct usages of the import within the file it is defined in.

        Returns:
            bool: True if the import is re-exported, False otherwise.
        """
        ...
    
    @property
    @noapidoc
    def names(self) -> Generator[tuple[str, Self | WildcardImport[Self]], None, None]:
        ...
    
    @property
    @noapidoc
    def viz(self) -> VizNode:
        ...
    
    @property
    @noapidoc
    def parent_symbol(self) -> Self:
        """Returns the parent symbol of the symbol."""
        ...
    
    def __hash__(self) -> int:
        ...
    
    @reader
    def __eq__(self, other: object) -> bool:
        ...
    
    @noapidoc
    @reader
    def remove_if_unused(self) -> None:
        ...
    


TImport = TypeVar("TImport", bound="Import")
class WildcardImport(Chainable, Generic[TImport]):
    """Class to represent one of many wildcard imports."""
    imp: TImport
    symbol: Importable
    def __init__(self, imp: TImport, symbol: Importable) -> None:
        ...
    


