
import atexit
import fcntl
import os
import time
from pathlib import Path
from telethon import TelegramClient as OriginalClient

_handles = []

def _close_handles():
    for handle in _handles:
        handle.close()

atexit.register(_close_handles)

def TelegramClient(session, *args, **kwargs):
    if not isinstance(session, (str, Path)):
        raise TypeError("Session guard requires a file session path.")

    path = Path(session).resolve()
    if not str(path).endswith(".session"):
        path = Path(str(path) + ".session")

    lock_path = str(path) + ".access.lock"
    fd = os.open(lock_path, os.O_CREAT | os.O_RDWR, 0o600)
    handle = os.fdopen(fd, "a+")
    deadline = time.monotonic() + 30

    while True:
        try:
            fcntl.flock(handle.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
            break
        except BlockingIOError:
            if time.monotonic() >= deadline:
                handle.close()
                raise RuntimeError("SESSION_BUSY_BEFORE_SEND")
            time.sleep(0.2)

    try:
        client = OriginalClient(session, *args, **kwargs)
    except BaseException:
        handle.close()
        raise

    _handles.append(handle)
    return client
