"""Rotate the shared gateway's mitmproxy CA (issue #450).

    python -m bot_bottle.orchestrator.rotate_ca

A deliberate CA rollover has two halves: drop the *persisted* CA so a fresh one
is minted, and drop the *running* gateway so its mitmproxy (which holds the old
CA in memory) is replaced. This one-shot command does both:

  1. Delete the persisted CA under the host gateway-CA dir — the next gateway
     start generates a new one (mitmproxy reuses an existing CA, generates only
     when absent).
  2. Force-remove the infra / standalone-gateway containers so the stale
     in-memory CA is gone; the next bottle launch's idempotent `ensure_running`
     brings the gateway back up and mints the fresh CA.

It does NOT re-provision the new CA into already-running bottles — those must be
re-attached so they install the new trust anchor. Rotation is thus an explicit,
operator-driven action with a brief egress interruption, not an automatic one.
"""

from __future__ import annotations

import sys
from pathlib import Path

from ..backend.docker.util import run_docker
from ..paths import host_gateway_ca_dir
from ..gateway import GATEWAY_NAME, rotate_gateway_ca

# The container whose mitmproxy would still be serving the old CA from memory:
# the per-host gateway (the data plane holds the CA; the split-out orchestrator
# never does).
_GATEWAY_CONTAINERS = (GATEWAY_NAME,)


def _out(msg: str) -> None:
    sys.stdout.write(f"rotate-ca: {msg}\n")


def main(argv: list[str] | None = None) -> int:
    del argv  # no flags — a single deliberate action
    ca_dir: Path = host_gateway_ca_dir()
    removed = rotate_gateway_ca(ca_dir)
    if removed:
        _out(f"removed {len(removed)} CA file(s) from {ca_dir}")
    else:
        _out(f"no persisted CA under {ca_dir}; a fresh one is minted on next start")

    # Drop any running gateway so its in-memory (now-stale) CA is replaced on
    # the next launch. `rm --force` on an absent name is a tolerated no-op.
    for name in _GATEWAY_CONTAINERS:
        proc = run_docker(["docker", "rm", "--force", name])
        if proc.returncode == 0 and proc.stdout.strip():
            _out(f"removed running container {name}")

    _out("done — the next bottle launch remints the CA; re-attach bottles to "
         "install the new trust anchor")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
