from __future__ import annotations

import asyncio
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from typing import Any, Optional

import black.concurrency as concurrency
from black import Mode, WriteBack
from black.report import Report


class FakeManager:
    shutdown_called: bool

    def __init__(self) -> None:
        self.shutdown_called = False

    def Lock(self) -> object:
        return object()

    def shutdown(self) -> None:
        self.shutdown_called = True


def test_manager_shutdown_called_for_diff(monkeypatch: Any, tmp_path: Path) -> None:
    """
    schedule_formatting() creates multiprocessing.Manager() for DIFF/COLOR_DIFF
    and must shut it down deterministically.
    """
    fake_manager = FakeManager()

    monkeypatch.setattr(concurrency, "Manager", lambda: fake_manager)

    def fake_format_file_in_place(
        src: Path,
        fast: bool,
        mode: Mode,
        write_back: WriteBack,
        lock: Optional[object],
    ) -> bool:
        assert lock is not None
        return False

    monkeypatch.setattr(concurrency, "format_file_in_place", fake_format_file_in_place)

    src = tmp_path / "a.py"
    src.write_text("x=1\n", encoding="utf8")

    async def run() -> None:
        loop = asyncio.get_running_loop()
        with ThreadPoolExecutor(max_workers=1) as executor:
            await concurrency.schedule_formatting(
                sources={src},
                fast=False,
                write_back=WriteBack.DIFF,
                mode=Mode(),
                report=Report(),
                loop=loop,
                executor=executor,
                no_cache=True,
            )

    asyncio.run(run())

    assert fake_manager.shutdown_called is True
