from __future__ import annotations

import io
import logging
import sys
import threading
from logging.handlers import RotatingFileHandler
from pathlib import Path


class RotatingLineStream(io.TextIOBase):
    """
    将 stdout/stderr 按行写入滚动日志文件。

    这里不复用业务 logger，避免 stdout 日志再次回流到控制台或普通业务日志文件，
    同时保证启动阶段的 print/uvicorn 输出也能按配置滚动。
    """

    def __init__(self, log_file: Path, max_bytes: int, backup_count: int):
        super().__init__()
        self._buffer = ""
        self._lock = threading.Lock()

        logger_name = f"moviepilot-stdio::{log_file}"
        self._logger = logging.getLogger(logger_name)
        self._logger.setLevel(logging.INFO)
        self._logger.propagate = False
        self._logger.handlers.clear()

        handler = RotatingFileHandler(
            filename=str(log_file),
            maxBytes=max_bytes,
            backupCount=backup_count,
            encoding="utf-8",
        )
        handler.setFormatter(logging.Formatter("%(message)s"))
        self._logger.addHandler(handler)

    @property
    def encoding(self) -> str:
        return "utf-8"

    def writable(self) -> bool:
        return True

    def isatty(self) -> bool:
        return False

    def write(self, message: str) -> int:
        if not message:
            return 0

        with self._lock:
            self._buffer += message.replace("\r\n", "\n")
            while "\n" in self._buffer:
                line, self._buffer = self._buffer.split("\n", 1)
                self._logger.info(line)
        return len(message)

    def flush(self) -> None:
        with self._lock:
            if self._buffer:
                self._logger.info(self._buffer)
                self._buffer = ""
            for handler in self._logger.handlers:
                handler.flush()


def configure_rotating_stdio(
    *, log_file: Path, max_bytes: int, backup_count: int
) -> RotatingLineStream:
    """
    将当前进程的 stdout/stderr 统一重定向到同一个滚动日志流。
    """

    log_file.parent.mkdir(parents=True, exist_ok=True)
    stream = RotatingLineStream(
        log_file=log_file,
        max_bytes=max_bytes,
        backup_count=backup_count,
    )
    sys.stdout = stream
    sys.stderr = stream
    return stream
