"""Local Docker build via buildx — the only CLI dependency for cube-agent."""

from __future__ import annotations

import asyncio
import logging
import shutil

logger = logging.getLogger(__name__)


class DockerBuildError(Exception):
    """Raised when a Docker build fails."""


def docker_available() -> bool:
    """Check if docker CLI is available."""
    return shutil.which("docker") is not None


async def docker_login(registry: str, token: str) -> None:
    """Login to a Docker registry using a token."""
    proc = await asyncio.create_subprocess_exec(
        "docker", "login", registry,
        "--username", "apollo",
        "--password-stdin",
        stdin=asyncio.subprocess.PIPE,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    _, stderr = await proc.communicate(token.encode())
    if proc.returncode != 0:
        raise DockerBuildError(f"Docker login failed: {stderr.decode().strip()}")


async def build_and_push(
    context_dir: str,
    tag: str,
    platforms: str = "linux/amd64,linux/arm64",
) -> str:
    """Build and push a Docker image using buildx.

    Args:
        context_dir: Build context directory (where Dockerfile lives).
        tag: Full image tag (e.g. "registry/repo:version").
        platforms: Comma-separated target platforms.

    Returns:
        Status message.
    """
    if not docker_available():
        raise DockerBuildError("Docker not found. Install Docker to build images.")

    cmd = [
        "docker", "buildx", "build",
        "--platform", platforms,
        "--tag", tag,
        "--output", "type=image,push=true",
        context_dir,
    ]

    logger.info("Building Docker image: %s", tag)

    proc = await asyncio.create_subprocess_exec(
        *cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=600)

    if proc.returncode != 0:
        raise DockerBuildError(f"Docker build failed: {stderr.decode().strip()}")

    return f"Image pushed: {tag}"
