from typing import Literal

import numpy as np
from numpy.typing import ArrayLike

class BinaryTree:
    data = ...
    sample_weight = ...
    sum_weight = ...

    idx_array = ...
    node_data = ...
    node_bounds = ...

    leaf_size = ...
    n_levels = ...
    n_nodes = ...

    dist_metric = ...
    euclidean = ...

    # variables to keep track of building & querying stats
    n_trims = ...
    n_leaves = ...
    n_splits = ...
    n_calls = ...

    valid_metrics = ...

    def __init__(self, data, leaf_size=40, metric="minkowski", sample_weight=None, **kwargs): ...
    def get_tree_stats(self) -> tuple[int, ...]: ...
    def reset_n_calls(self) -> None: ...
    def get_n_calls(self) -> int: ...
    def get_arrays(self) -> tuple[np.ndarray, ...]: ...
    def dist(self, x1, x2, size) -> float: ...
    def rdist(self, x1, x2, size) -> float: ...
    def query(
        self,
        X: ArrayLike,
        k: int = 1,
        return_distance: bool = True,
        dualtree: bool = False,
        breadth_first: bool = False,
        sort_results: bool = True,
    ) -> np.ndarray | tuple[np.ndarray, np.ndarray]: ...
    def query_radius(
        self,
        X: ArrayLike,
        r: float | ArrayLike,
        return_distance: bool = False,
        count_only: bool = False,
        sort_results: bool = False,
    ) -> np.ndarray | tuple[np.ndarray, np.ndarray]: ...
    def kernel_density(
        self,
        X: ArrayLike,
        h: float,
        kernel: Literal["gaussian", "tophat", "epanechnikov", "exponential", "linear", "cosine"] = "gaussian",
        atol: float = 0,
        rtol: float = 1e-8,
        breadth_first: bool = True,
        return_log: bool = False,
    ) -> np.ndarray: ...
    def two_point_correlation(self, X: ArrayLike, r: ArrayLike, dualtree: bool = False) -> np.ndarray: ...
