"""`deploy/production.sh` refuses before it touches anything (Stream K7; plan W17). What it cost before:
`--seed-db` ran `pg_restore --clean --if-exists ... || true`, so a restore that failed halfway reported
success and left production half-replaced; nothing compared what arrived with what left. These run the
script's argument handling and the refusals that fire before any ssh, docker or database call, in
seconds, with no network and no container: the database half is proven by the rehearsal on dfp-devdb
(`.logs/runs/rehearsal-2026-09-17-k7-replace.md`)."""
from __future__ import annotations

import os
import pathlib
import subprocess

import pytest

ROOT = pathlib.Path(__file__).resolve().parents[2]
SCRIPT = ROOT / "deploy" / "production.sh"
DUMP_SCRIPT = ROOT / "deploy" / "launch-dump.sh"


def run(*args: str, script: pathlib.Path = SCRIPT) -> subprocess.CompletedProcess:
    # A host that cannot exist: were a refusal ever to fall through to ssh, it fails fast, never deploys.
    env = {**os.environ, "DFP_PROD_HOST": "nobody@invalid.invalid", "DFP_PG_READER": "no-such-container"}
    return subprocess.run(["bash", str(script), *args], capture_output=True, text=True, timeout=20, env=env, stdin=subprocess.DEVNULL)


@pytest.fixture
def dump(tmp_path) -> pathlib.Path:
    path = tmp_path / "staging.dump"
    path.write_bytes(b"not a real dump")
    for side, text in (("counts", "brands\t3\n"), ("head", "d2e3f4a5b6c7\n"), ("sources", "shopify-pty\tt\t1.00\tdeclared\t\n")):
        (tmp_path / f"staging.dump.{side}").write_text(text)
    return path


def test_the_scripts_parse():
    for script in (SCRIPT, DUMP_SCRIPT):
        assert subprocess.run(["bash", "-n", str(script)], capture_output=True).returncode == 0, script


def test_seed_db_is_gone_and_says_what_replaced_it():
    r = run("--seed-db", "backups/x.dump")
    assert r.returncode == 2 and "--seed-db is removed" in r.stderr and "--replace-db" in r.stderr


def test_an_unknown_argument_and_a_missing_value_are_refused():
    assert run("--frobnicate").returncode == 2
    r = run("--replace-db")
    assert r.returncode == 2 and "needs a dump file" in r.stderr


def test_local_is_only_a_rehearsal_of_the_replace_and_never_against_staging(dump):
    r = run("--local")
    assert r.returncode == 2 and "rehearses --replace-db only" in r.stderr
    r = run("--replace-db", str(dump), "--local")
    assert r.returncode == 2 and "would replace staging" in r.stderr, "the default container is staging's"
    r = run("--replace-db", str(dump), "--local", "--db-container", "dutyfreeprofessor-db", "--db", "dfp")
    assert r.returncode == 2 and "would replace staging" in r.stderr


def test_the_replace_and_caddy_are_separate_steps(dump):
    r = run("--replace-db", str(dump), "--caddy")
    assert r.returncode == 2 and "separate steps" in r.stderr


def test_a_missing_dump_or_sidecar_is_refused_before_anything_runs(dump, tmp_path):
    r = run("--replace-db", str(tmp_path / "nope.dump"), "--local", "--db-container", "dfp-devdb")
    assert r.returncode == 1 and "no dump at" in r.stderr
    for side in ("counts", "head", "sources"):
        (tmp_path / f"staging.dump.{side}").rename(tmp_path / f"hidden.{side}")
        r = run("--replace-db", str(dump), "--local", "--db-container", "dfp-devdb", "--app-exec", "true")
        assert r.returncode == 1 and f"staging.dump.{side} is missing" in r.stderr and "launch-dump.sh" in r.stderr
        (tmp_path / f"hidden.{side}").rename(tmp_path / f"staging.dump.{side}")


def test_a_rehearsal_needs_the_app_cli_on_its_own_database(dump):
    r = run("--replace-db", str(dump), "--local", "--db-container", "dfp-devdb", "--db", "dfp_prod_like")
    assert r.returncode == 1 and "--local needs --app-exec" in r.stderr


def test_a_dump_that_cannot_be_read_is_refused_and_nothing_is_dumped_or_dropped(dump):
    r = run("--replace-db", str(dump), "--local", "--db-container", "dfp-devdb", "--db", "dfp_prod_like", "--app-exec", "true", "--dry-run")
    assert r.returncode == 1 and "could not read" in r.stderr
    assert "pg_dump" not in r.stdout and "drop schema" not in r.stdout


def test_launch_dump_refuses_an_unknown_argument_and_documents_itself():
    assert run("--nope", script=DUMP_SCRIPT).returncode == 2
    r = run("--help", script=DUMP_SCRIPT)
    assert r.returncode == 0 and ".counts" in r.stdout and "production.sh --replace-db" in r.stdout
