#!/usr/bin/env python3
import argparse
import shlex
import subprocess
import sys
from pathlib import Path

def run(cmd: str, check: bool = True, cwd: Path | None = None):
    where = f" (cwd: {cwd})" if cwd else ""
    print(f"\n$ {cmd}{where}")
    return subprocess.run(cmd, shell=True, check=check, text=True, cwd=str(cwd) if cwd else None)

def detect_compose_cmd() -> str:
    try:
        subprocess.run(["docker", "compose", "version"],
                       check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return "docker compose"
    except Exception:
        return "docker-compose"

def container_exists(name: str) -> bool:
    cmd = f"docker ps -aq -f name=^{shlex.quote(name)}$"
    out = subprocess.check_output(cmd, shell=True, text=True).strip()
    return bool(out)

def image_exists(image: str) -> bool:
    cmd = f"docker images -q {shlex.quote(image)}"
    out = subprocess.check_output(cmd, shell=True, text=True).strip()
    return bool(out)

def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        prog="docker-deploy",
        description=(
            "📦 Docker deploy helper — build & restart a service cleanly.\n\n"
            "Cosa fa:\n"
            "  1️⃣ Ferma ed elimina il container corrente\n"
            "  2️⃣ Rimuove l'immagine associata\n"
            "  3️⃣ Ricostruisce la nuova immagine (opz. senza cache)\n"
            "  4️⃣ Avvia il container\n"
            "  5️⃣ Mostra stato e ultimi log\n\n"
            "💡 Suggerimento: posizionati nella root del progetto e lancia direttamente:\n"
            "    docker-deploy --env-file .prodenv\n\n"
            "Oppure per forzare rebuild completo:\n"
            "    docker-deploy --no-cache --env-file .prodenv"
        ),
        formatter_class=argparse.RawTextHelpFormatter,
    )

    parser.add_argument(
        "--service",
        default=Path.cwd().name,
        help="Nome del servizio/container (default: nome della cartella corrente)"
    )
    parser.add_argument(
        "--compose-file",
        default="docker-compose.yaml",
        help="File docker compose (default: docker-compose.yaml)"
    )
    parser.add_argument(
        "--env-file",
        default=None,
        help="Path al file .env / .prodenv (opzionale)"
    )
    parser.add_argument(
        "--context",
        default="default",
        help="Docker context da usare (default: default)"
    )
    parser.add_argument(
        "--no-cache",
        action="store_true",
        help="Esegue la build senza usare la cache Docker"
    )

    args = parser.parse_args(argv)

    project_dir = Path.cwd()
    compose_file = project_dir / args.compose_file
    if not compose_file.exists():
        print(f"❌ Compose file non trovato: {compose_file}")
        return 1

    env_arg = f"--env-file {shlex.quote(str(Path(args.env_file).resolve()))}" if args.env_file else ""
    compose = detect_compose_cmd()
    svc = args.service
    image_name = f"{svc}:latest"

    try:
        run(f"docker context use {shlex.quote(args.context)}")

        print(f"\n=== 🚢 Deploying: {svc} ===")

        # 1️⃣ Stop & rm
        if container_exists(svc):
            run(f"docker stop {shlex.quote(svc)}", check=False)
            run(f"docker rm -f {shlex.quote(svc)}", check=False)
        else:
            print(f"(no existing container named '{svc}')")

        # 2️⃣ Remove image
        if image_exists(image_name):
            run(f"docker rmi -f {shlex.quote(image_name)}", check=False)
        else:
            print(f"(no existing image '{image_name}')")

        # 3️⃣ Build
        build_cmd = f"{compose} -f {shlex.quote(str(compose_file))} {env_arg} build"
        if args.no_cache:
            build_cmd += " --no-cache"
        build_cmd += f" {shlex.quote(svc)}"
        run(build_cmd, cwd=project_dir)

        # 4️⃣ Up
        run(f"{compose} -f {shlex.quote(str(compose_file))} {env_arg} up -d {shlex.quote(svc)}",
            cwd=project_dir)

        # 5️⃣ ps + logs
        run(f"{compose} -f {shlex.quote(str(compose_file))} ps", cwd=project_dir, check=False)
        run(f"{compose} -f {shlex.quote(str(compose_file))} logs -n 100 {shlex.quote(svc)}",
            cwd=project_dir, check=False)

    finally:
        run("docker context use default", check=False)

    print("\n✅ Deployment complete.")
    return 0

if __name__ == "__main__":
    sys.exit(main())