"""Tests for ``mgf-common federation-sync``.

Closes [PAPER-57](../../../../FEEDBACK.md). The subcommand prints the
federation-sync message with a live pin window so consumers and
AI agents never paste a stale ``>=0.X,<0.Y`` literal.
"""

from __future__ import annotations

import argparse
import io
from contextlib import redirect_stdout

import mgf.common
from mgf.common.cli._exit_codes import EXIT_SUCCESS

from mgf.fed.cli._federation_sync import (
    add_federation_sync_args,
    run_federation_sync,
)
from mgf.fed.cli._version_pin import current_pin_window


def _make_args() -> argparse.Namespace:
    return argparse.Namespace()


class TestRunFederationSync:
    def test_prints_message_and_returns_exit_ok(self) -> None:
        buf = io.StringIO()
        with redirect_stdout(buf):
            rc = run_federation_sync(_make_args())
        assert rc == EXIT_SUCCESS
        out = buf.getvalue()
        assert "federation sync" in out.lower()

    def test_message_includes_live_pin_window(self) -> None:
        buf = io.StringIO()
        with redirect_stdout(buf):
            run_federation_sync(_make_args())
        out = buf.getvalue()
        # The pin window in the message must match what the helper
        # returns RIGHT NOW — that's the whole point of PAPER-57.
        assert current_pin_window() in out

    def test_message_includes_installed_version(self) -> None:
        # The "mgf-common is at v<X.Y.Z>" line must reference the
        # actually-installed version.
        buf = io.StringIO()
        with redirect_stdout(buf):
            run_federation_sync(_make_args())
        out = buf.getvalue()
        assert mgf.common.__version__ in out

    def test_message_directs_to_catch_up_and_feedback(self) -> None:
        # The message routes consumers to the right next-actions:
        # `mgf-common catch-up` (verification) and `mgf-common feedback`
        # (raise friction). Both are first-class subcommands.
        buf = io.StringIO()
        with redirect_stdout(buf):
            run_federation_sync(_make_args())
        out = buf.getvalue()
        assert "catch-up" in out
        assert "feedback" in out


class TestAddFederationSyncArgs:
    def test_accepts_a_subparser_without_raising(self) -> None:
        # Future-flag-friendly shape: register adds nothing today but
        # MUST not crash when called by the dispatcher.
        parser = argparse.ArgumentParser()
        add_federation_sync_args(parser)
        # Parsing an empty argv with no flags registered is the smoke
        # test that the subcommand can be invoked.
        ns = parser.parse_args([])
        assert isinstance(ns, argparse.Namespace)
