from collections.abc import Callable
from http.server import SimpleHTTPRequestHandler
from ralium.util import AbsolutePath, RelativePath, UrlPath
from _typeshed import StrOrBytesPath, BytesPath, StrPath
from pathlib import Path

from typing import (
    LiteralString, 
    BinaryIO, 
    overload, 
    AnyStr, 
    Tuple, 
    Dict,
    List
)

def reload_ralium() -> None: ...

class BundledHTTPRequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self) -> None: ...
    def do_HEAD(self) -> None: ...
    def send_head(self) -> bytes | None: ...
    def translate_path(self, path: StrPath) -> str: ...
    def copyfile(self, fsrc: bytes, fdst: BinaryIO) -> None: ...

class File:
    __slots__: Tuple[LiteralString]

    def __init__(self, relpath: RelativePath, content: bytes) -> None: ...
    def __str__(self) -> AnyStr: ...
    def __repr__(self) -> AnyStr: ...
    
class Bundle:
    __slots__: Tuple[LiteralString]

    def __init__(self, *, url: UrlPath, page: File, server: File, styles: List[File]): ...
    def __repr__(self) -> AnyStr: ...

class FileSystem:
    __slots__: Tuple[LiteralString]

    def __init__(self, *, images: List[File], styles: List[File], bundles: List[Bundle]) -> None: ...
    def __add_file(self, file: File) -> None: ...

    @overload
    def open(self, filename: Path) -> bytes: ...
    @overload
    def open(self, filename: StrPath) -> bytes: ...
    @overload
    def open(self, filename: BytesPath) -> bytes: ...
    
    @overload
    def exists(self, path: Path) -> bool: ...
    @overload
    def exists(self, path: StrPath) -> bool: ...
    @overload
    def exists(self, path: BytesPath) -> bool: ...

    def mkdirs(self, *dirs: Tuple[StrPath]) -> None: ...
    def mkfile(self, filename: str, data: bytes) -> None: ...
    def mkfiles(self, **files: Dict[str, bytes]) -> None: ...

class PyBundler:
    __slots__: Tuple[LiteralString]

    @overload
    def __init__(self, pyfile: StrOrBytesPath, project: StrOrBytesPath) -> None: ...
    @overload
    def __init__(self, pyfile: Path, project: StrOrBytesPath) -> None: ...
    @overload
    def __init__(self, pyfile: StrOrBytesPath, project: Path) -> None: ...
    @overload
    def __init__(self, pyfile: Path, project: Path) -> None: ...

    def view(self) -> List[AnyStr]: ...
    def relpath(self, path: Path) -> RelativePath: ...
    def collect(self, dir: AbsolutePath, callback: Callable[[Path], bool]) -> List[File]: ...

    @overload
    @staticmethod
    def isstyle(filename: Path) -> bool: ...
    @overload
    @staticmethod
    def isstyle(filename: StrPath) -> bool: ...
    @overload
    @staticmethod
    def isstyle(filename: BytesPath) -> bool: ...
    
    @overload
    @staticmethod
    def isimage(filename: Path) -> bool: ...
    @overload
    @staticmethod
    def isimage(filename: StrPath) -> bool: ...
    @overload
    @staticmethod
    def isimage(filename: BytesPath) -> bool: ...
    
    @overload
    @staticmethod
    def get_content(filename: Path) -> bytes: ...
    @overload
    @staticmethod
    def get_content(filename: StrPath) -> bytes: ...
    @overload
    @staticmethod
    def get_content(filename: BytesPath) -> bytes: ...