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

from collections.abc import Generator, Sequence
from contextlib import contextmanager
from enum import IntEnum, unique
from typing import Any, TYPE_CHECKING
from codeowners import CodeOwners as CodeOwnersParser
from git import Commit as GitCommit
from rustworkx import PyDiGraph, WeightedEdgeList
from codegen.git import RepoOperator
from graph_sitter.codebase.config import CodebaseConfig, ProjectConfig, SessionOptions
from graph_sitter.codebase.config_parser import ConfigParser
from graph_sitter.codebase.diff_lite import DiffLite
from graph_sitter.codebase.flagging.flags import Flags
from graph_sitter.codebase.transaction_manager import TransactionManager
from graph_sitter.core.autocommit import AutoCommit, commiter
from graph_sitter.core.dataclasses.usage import Usage
from graph_sitter.core.directory import Directory
from graph_sitter.core.external.dependency_manager import DependencyManager
from graph_sitter.core.external.language_engine import LanguageEngine
from graph_sitter.core.interfaces.importable import Importable
from graph_sitter.core.node_id_factory import NodeId
from graph_sitter.enums import Edge, EdgeType, NodeType, ProgrammingLanguage
from graph_sitter.perf import stopwatch, stopwatch_with_sentry
from graph_sitter.typescript.external.ts_declassify.ts_declassify import TSDeclassify
from graph_sitter.codebase.node_classes.node_classes import NodeClasses
from graph_sitter.core.expressions import Expression
from graph_sitter.core.external_module import ExternalModule
from graph_sitter.core.file import SourceFile
from graph_sitter.core.parser import Parser

if TYPE_CHECKING:
    ...
logger = ...
GLOBAL_FILE_IGNORE_LIST = ...
@unique
class SyncType(IntEnum):
    DELETE = ...
    REPARSE = ...
    ADD = ...


def get_node_classes(programming_language: ProgrammingLanguage) -> NodeClasses:
    ...

class CodebaseGraph:
    """MultiDiGraph Wrapper with TransactionManager"""
    node_classes: NodeClasses
    programming_language: ProgrammingLanguage
    repo_path: str
    repo_name: str
    codeowners_parser: CodeOwnersParser | None
    config: CodebaseConfig
    transaction_manager: TransactionManager
    pending_syncs: list[DiffLite]
    all_syncs: list[DiffLite]
    _autocommit: AutoCommit
    pending_files: set[SourceFile]
    generation: int
    parser: Parser[Expression]
    synced_commit: GitCommit | None
    directories: dict[str, Directory]
    base_url: str | None
    extensions: list[str]
    config_parser: ConfigParser | None
    dependency_manager: DependencyManager | None
    language_engine: LanguageEngine | None
    _computing = ...
    _graph: PyDiGraph[Importable, Edge]
    filepath_idx: dict[str, NodeId]
    _ext_module_idx: dict[str, NodeId]
    flags: Flags
    session_options: SessionOptions = ...
    projects: list[ProjectConfig]
    def __init__(self, projects: list[ProjectConfig], config: CodebaseConfig = ...) -> None:
        """Initializes codebase graph and TransactionManager"""
        ...
    
    def __repr__(self): # -> str:
        ...
    
    @stopwatch_with_sentry(name="build_graph")
    @commiter
    def build_graph(self, repo_operator: RepoOperator) -> None:
        """Builds a codebase graph based on the current file state of the given repo operator"""
        ...
    
    @stopwatch
    @commiter
    def apply_diffs(self, diff_list: list[DiffLite]) -> None:
        """Applies the given set of diffs to the graph in order to match the current file system content"""
        ...
    
    @stopwatch
    def undo_applied_diffs(self) -> None:
        ...
    
    def save_commit(self, commit: GitCommit) -> None:
        ...
    
    @stopwatch
    def prune_graph(self) -> None:
        ...
    
    def build_subgraph(self, nodes: list[NodeId]) -> PyDiGraph[Importable, Edge]:
        """Builds a subgraph from the given set of nodes"""
        ...
    
    def get_node(self, node_id: int) -> Any:
        ...
    
    def get_nodes(self, node_type: NodeType | None = ..., exclude_type: NodeType | None = ...) -> list[Importable]:
        ...
    
    def get_edges(self) -> list[tuple[NodeId, NodeId, EdgeType, Usage | None]]:
        ...
    
    def get_file(self, file_path: str, ignore_case: bool = ...) -> SourceFile | None:
        ...
    
    def get_external_module(self, module: str, import_name: str) -> ExternalModule | None:
        ...
    
    def add_node(self, node: Importable) -> int:
        ...
    
    def add_child(self, parent: NodeId, node: Importable, type: EdgeType, usage: Usage | None = ...) -> int:
        ...
    
    def has_node(self, node_id: NodeId): # -> bool:
        ...
    
    def has_edge(self, u: NodeId, v: NodeId, edge: Edge): # -> bool:
        ...
    
    def add_edge(self, u: NodeId, v: NodeId, type: EdgeType, usage: Usage | None = ...) -> None:
        ...
    
    def add_edges(self, edges: list[tuple[NodeId, NodeId, Edge]]) -> None:
        ...
    
    @property
    def nodes(self): # -> list[Importable[Any]]:
        ...
    
    @property
    def edges(self) -> WeightedEdgeList[Edge]:
        ...
    
    def predecessor(self, n: NodeId, *, edge_type: EdgeType | None) -> Importable:
        ...
    
    def predecessors(self, n: NodeId, edge_type: EdgeType | None = ...) -> Sequence[Importable]:
        ...
    
    def successors(self, n: NodeId, *, edge_type: EdgeType | None = ..., sort: bool = ...) -> Sequence[Importable]:
        ...
    
    def get_edge_data(self, *args, **kwargs) -> set[Edge]:
        ...
    
    def in_edges(self, n: NodeId) -> WeightedEdgeList[Edge]:
        ...
    
    def out_edges(self, n: NodeId) -> WeightedEdgeList[Edge]:
        ...
    
    def remove_node(self, n: NodeId): # -> None:
        ...
    
    def remove_edge(self, u: NodeId, v: NodeId, *, edge_type: EdgeType | None = ...): # -> None:
        ...
    
    def check_changes(self) -> None:
        ...
    
    def write_files(self, files: set[str] | None = ...) -> None:
        ...
    
    @commiter
    def commit_transactions(self, sync_graph: bool = ..., files: set[str] | None = ...) -> None:
        """Commits all transactions to the codebase, and syncs the graph to match the latest file changes.
        Should be called at the end of `execute` for every codemod group run.

        Arguments:
            sync_graph (bool): If True, syncs the graph with the latest set of file changes
            files (set[str] | None): If provided, only commits transactions for the given set of files
        """
        ...
    
    @commiter
    def add_single_file(self, filepath: str) -> None:
        """Adds a file to the graph and computes it's dependencies"""
        ...
    
    @contextmanager
    def session(self, sync_graph: bool = ..., commit: bool = ..., session_options: SessionOptions = ...) -> Generator[None, None, None]:
        ...
    
    def get_directory(self, directory_path: str, create_on_missing: bool = ..., ignore_case: bool = ...) -> Directory | None:
        """Returns the directory object for the given path, or None if the directory does not exist.

        If create_on_missing is set, use a recursive strategy to create the directory object and all subdirectories.
        """
        ...
    
    def remove_directory(self, directory_path: str, force: bool = ..., cleanup: bool = ...) -> None:
        """Removes a directory from the graph"""
        ...
    
    _ts_declassify: TSDeclassify | None = ...
    @property
    def ts_declassify(self) -> TSDeclassify:
        ...
    


