"""Integration: the Docker launch broker starts and removes a real container.

Gated on a reachable Docker daemon (skips cleanly otherwise). Uses a tiny
image; the container may exit immediately — we only assert it exists after
launch and is gone after teardown.
"""

from __future__ import annotations

import secrets
import subprocess
import unittest

from bot_bottle.orchestrator.broker import LaunchRequest, sign_request
from bot_bottle.orchestrator.docker_broker import DockerBroker, container_name
from tests._backend import skip_unless_backend

IMAGE = "busybox"


@skip_unless_backend("docker")
class TestDockerBrokerIntegration(unittest.TestCase):
    def setUp(self) -> None:
        self.secret = secrets.token_bytes(16)
        self.broker = DockerBroker(self.secret)
        self.bottle_id = "itest" + secrets.token_hex(4)
        self.name = container_name(self.bottle_id)
        self.addCleanup(
            lambda: subprocess.run(
                ["docker", "rm", "--force", self.name],
                stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False,
            )
        )

    def _exists(self) -> bool:
        proc = subprocess.run(
            ["docker", "ps", "-a", "--filter", f"name=^{self.name}$",
             "--format", "{{.Names}}"],
            stdout=subprocess.PIPE, text=True, check=False,
        )
        return self.name in proc.stdout.split()

    def _submit(self, req: LaunchRequest) -> None:
        self.broker.submit(sign_request(req, self.secret))

    def test_launch_creates_then_teardown_removes(self) -> None:
        self._submit(
            LaunchRequest(op="launch", bottle_id=self.bottle_id, image_ref=IMAGE)
        )
        self.assertTrue(self._exists(), "container should exist after launch")
        self._submit(LaunchRequest(op="teardown", bottle_id=self.bottle_id))
        self.assertFalse(self._exists(), "container should be gone after teardown")


if __name__ == "__main__":
    unittest.main()
