import time
from pathlib import Path


class ProgressFile:
    def __init__(self, path: Path, chunk_size=100_000, log_interval=5.0):
        self.path = Path(path)
        self.chunk_size = chunk_size
        self.log_interval = log_interval

        self.f = None
        self.total = 0
        self.sent = 0
        self._last_log_t = 0.0

    def __enter__(self):
        if not self.path.is_file():
            raise FileNotFoundError(self.path)

        self.f = self.path.open("rb")
        self.total = self.path.stat().st_size
        self.sent = 0
        self._last_log_t = 0.0
        return self

    def __exit__(self, exc_type, exc, tb):
        if self.f:
            self.f.close()
        return False

    def __len__(self):
        return self.total

    def read(self, n=-1):
        if not self.f:
            raise RuntimeError("ProgressFile must be used within a with block")

        chunk = self.f.read(self.chunk_size if n == -1 else n)
        if not chunk:
            self._log(force=True)
            return b""

        self.sent += len(chunk)
        self._log()
        return chunk

    def _log(self, force=False):
        now = time.time()
        if force or (now - self._last_log_t) >= self.log_interval:
            self._last_log_t = now
            pct = (self.sent / self.total * 100) if self.total else 0.0
            print(
                f"upload progress: {self.sent}/{self.total} bytes ({pct:.1f}%)",
                flush=True,
            )
