"""Tests for the operability verbs — version / doctor / explain / bundle.

These exercise the OP-01/OP-02/OP-05/OP-07 feature surface against the local
``fake`` provider (offline; no live cloud call), plus the no-credentials failure
path of ``doctor`` (exit = failed-check count).
"""

from __future__ import annotations

import json
import tarfile
from typing import TYPE_CHECKING

from mgf.cloud.__main__ import main

if TYPE_CHECKING:
    from pathlib import Path

    import pytest


# ---------------------------------------------------------------------------
# version (OP-01)
# ---------------------------------------------------------------------------
def test_version_rich(capsys: pytest.CaptureFixture[str]) -> None:
    assert main(["version"]) == 0
    out = capsys.readouterr().out
    assert "mgf-cloud" in out
    assert "python:" in out
    assert "platform:" in out
    assert "deps:" in out


def test_version_json(capsys: pytest.CaptureFixture[str]) -> None:
    assert main(["version", "--json"]) == 0
    facts = json.loads(capsys.readouterr().out)
    assert facts["name"] == "mgf-cloud"
    assert "version" in facts
    assert "pydantic" in facts["deps"]
    # The single-sourced version matches the live __version__ (AP-13).
    import mgf.cloud

    assert facts["version"] == mgf.cloud.__version__


# ---------------------------------------------------------------------------
# doctor (OP-02)
# ---------------------------------------------------------------------------
def test_doctor_fake_all_ok(capsys: pytest.CaptureFixture[str]) -> None:
    assert main(["doctor", "--provider", "fake"]) == 0
    out = capsys.readouterr().out
    assert "providers" in out
    assert "credentials" in out
    assert "rates" in out
    assert "fail" not in out


def test_doctor_json_shape(capsys: pytest.CaptureFixture[str]) -> None:
    assert main(["doctor", "--provider", "fake", "--json"]) == 0
    report = json.loads(capsys.readouterr().out)
    assert report["app_name"] == "mgf-cloud"
    assert report["overall_status"] == "ok"
    names = {s["name"] for s in report["sections"]}
    assert {"providers", "provider-sdk", "credentials", "rates"} <= names


def test_doctor_exit_is_failed_check_count(
    monkeypatch: pytest.MonkeyPatch,
    capsys: pytest.CaptureFixture[str],
    tmp_path: Path,
) -> None:
    # No credentials resolvable → the credentials check fails (exit 1), but the
    # offline checks (providers/sdk/rates) still pass. Isolate from any real
    # clouds.yaml on the host by pointing the env override at a missing file and
    # clearing OS_*.
    monkeypatch.delenv("OS_AUTH_URL", raising=False)
    monkeypatch.setenv("MGF_CLOUD_CLOUDS_YAML", str(tmp_path / "absent.yaml"))
    rc = main(["doctor", "--provider", "infomaniak"])
    out = capsys.readouterr().out
    assert "[✗ fail ] credentials" in out
    assert rc == 1


def test_doctor_bad_rates_file(
    monkeypatch: pytest.MonkeyPatch,
    capsys: pytest.CaptureFixture[str],
    tmp_path: Path,
) -> None:
    monkeypatch.delenv("MGF_CLOUD_RATES", raising=False)
    missing = tmp_path / "nope.toml"
    rc = main(["doctor", "--provider", "fake", "--rates", str(missing)])
    out = capsys.readouterr().out
    assert "[✗ fail ] rates" in out
    assert rc == 1


# ---------------------------------------------------------------------------
# explain (OP-05)
# ---------------------------------------------------------------------------
def test_explain_fake(capsys: pytest.CaptureFixture[str]) -> None:
    assert main(["explain", "--provider", "fake"]) == 0
    out = capsys.readouterr().out
    assert "provider" in out
    assert "fake" in out


def test_explain_reports_source_and_redacts(
    capsys: pytest.CaptureFixture[str],
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    clouds = tmp_path / "clouds.yaml"
    clouds.write_text(
        "clouds:\n"
        "  openstack:\n"
        "    auth:\n"
        "      auth_url: https://api.example/v3\n"
        "      application_credential_id: the-id\n"
        "      application_credential_secret: SUPERSECRET\n",
        encoding="utf-8",
    )
    monkeypatch.delenv("OS_AUTH_URL", raising=False)
    assert (
        main(["explain", "--provider", "infomaniak", "--clouds-yaml", str(clouds), "--json"]) == 0
    )
    facts = json.loads(capsys.readouterr().out)
    assert facts["auth_url"] == "https://api.example/v3"
    assert "explicit --clouds-yaml" in facts["source"]
    assert facts["application_credential_id"] == "the-id"
    # The secret is SecretStr-redacted, never echoed in the clear.
    assert "SUPERSECRET" not in json.dumps(facts)
    assert facts["application_credential_secret"] == "**********"


# ---------------------------------------------------------------------------
# bundle (OP-07)
# ---------------------------------------------------------------------------
def test_bundle_writes_redacted_tarball(
    capsys: pytest.CaptureFixture[str],
    tmp_path: Path,
) -> None:
    out = tmp_path / "bundle.tar.gz"
    assert main(["bundle", "--provider", "fake", "-o", str(out)]) == 0
    assert out.is_file()
    with tarfile.open(out, "r:gz") as tar:
        names = tar.getnames()
    assert "mgf-cloud-bundle/version.json" in names
    assert "mgf-cloud-bundle/doctor.txt" in names
    assert "mgf-cloud-bundle/explain.txt" in names
    assert "mgf-cloud-bundle/README.txt" in names
