"""Unit mirror for ``mgf.fed.cli._validate`` (TS-01).

Exercises the three exit-code paths of ``validate()`` — valid config, schema
failure, and unreadable/malformed input — through in-memory streams.
"""

from __future__ import annotations

import io
from pathlib import Path

from mgf.common.cli import EXIT_CONFIG_ERROR, EXIT_OPERATION_ERROR, EXIT_SUCCESS

from mgf.fed.cli._validate import validate


def test_valid_config_returns_success(tmp_path: Path) -> None:
    cfg = tmp_path / "ok.yaml"
    cfg.write_text("logging:\n  level: INFO\n", encoding="utf-8")
    out, err = io.StringIO(), io.StringIO()
    rc = validate(cfg, app_name="demo", app_version="1.0", out=out, err=err)
    assert rc == EXIT_SUCCESS
    assert "Schema valid" in out.getvalue()
    assert "for demo v1.0" in out.getvalue()


def test_missing_file_is_operation_error(tmp_path: Path) -> None:
    out, err = io.StringIO(), io.StringIO()
    rc = validate(tmp_path / "nope.yaml", out=out, err=err)
    assert rc == EXIT_OPERATION_ERROR
    assert "failed to read" in err.getvalue()


def test_non_mapping_top_level_is_config_error(tmp_path: Path) -> None:
    cfg = tmp_path / "list.yaml"
    cfg.write_text("- just\n- a\n- list\n", encoding="utf-8")
    out, err = io.StringIO(), io.StringIO()
    rc = validate(cfg, out=out, err=err)
    assert rc == EXIT_CONFIG_ERROR
    assert "MUST be a mapping" in err.getvalue()


def test_invalid_yaml_is_operation_error(tmp_path: Path) -> None:
    cfg = tmp_path / "bad.yaml"
    cfg.write_text("key: [unterminated\n", encoding="utf-8")
    out, err = io.StringIO(), io.StringIO()
    rc = validate(cfg, out=out, err=err)
    assert rc == EXIT_OPERATION_ERROR
    assert "YAML parse error" in err.getvalue()
