from typing import List, Tuple, Iterator, Dict, Sequence, Optional, Iterable

from whatshap.core import ReadSet

class ClusterEditingSolver:
    def __init__(self, m: TriangleSparseMatrix, bundle_edges: bool): ...
    def run(self) -> List[List[int]]: ...

class AlleleMatrix:
    def __init__(self, rs: Optional[ReadSet]): ...

class TriangleSparseMatrix:
    def __init__(self): ...
    def get(self, i: int, j: int) -> float: ...
    def set(self, i: int, j: int, value: float) -> None: ...
    def size(self) -> int: ...
    def getEntries(self) -> List[Tuple[int, int]]: ...
    def __iter__(self) -> Iterator[Tuple[int, int]]: ...
    def __len__(self) -> int: ...

# class ReadScoring:
#     def __init__(self): ...
def scoreReadset(
    readset: ReadSet, min_overlap: int, ploidy: int, err: float = ...
) -> TriangleSparseMatrix: ...

class HaploThreader:
    def __init__(
        self,
        ploidy: int,
        switch_cost: float,
        affine_switch_cost: float,
        symmetry_optimization: bool,
        row_limit: int,
    ): ...
    def computePathsBlockwise(
        self,
        block_starts: List[int],
        coverage_map: List[List[int]],
        coverage: List[List[float]],
        consensus: List[List[int]],
        genotypes: List[Dict[int, int]],
    ) -> List[List[int]]: ...
    def computePaths(
        self,
        start: int,
        end: int,
        coverage_map: List[List[int]],
        coverage: List[List[float]],
        consensus: List[List[int]],
        genotypes: List[Dict[int, int]],
    ) -> List[List[int]]: ...

class SwitchFlipCalculator:
    def __init__(self, ploidy: int, switch_cost: int = ..., flip_cost: int = ...): ...
    def compute_switch_flips_poly(
        self, phasing0: Sequence[str], phasing1: Sequence[str]
    ) -> Tuple[float, float, List[int], List[List[int]], List[List[int]]]: ...

def compute_polyploid_genotypes(
    readset: ReadSet, ploidy: int, positions: Optional[Iterable[int]] = ...
) -> List[List[int]]: ...
