"""Author identity rules (SPEC §7.3).

The split-attribution rule is the load-bearing piece: configured user
goes into the commit header, Attractor goes into the trailer. We
verify the rendered signature + message reflect both cases.
"""

import pygit2
import pytest

from attractor.checkpoint import (
    ATTRACTOR_EMAIL,
    ATTRACTOR_NAME,
    Author,
)


# [unit->REQ-STORE-AUTHOR-ID]
class TestAuthorConstruction:
    """`Author(...)` enforces the XOR invariant on user_name/user_email."""

    def test_no_user_is_engine_only(self) -> None:
        a = Author()
        assert a.is_engine_only is True

    def test_both_set_is_user_configured(self) -> None:
        a = Author(user_name="X", user_email="x@example.com")
        assert a.is_engine_only is False

    def test_name_without_email_raises(self) -> None:
        with pytest.raises(ValueError, match="both be set"):
            Author(user_name="X")

    def test_email_without_name_raises(self) -> None:
        with pytest.raises(ValueError, match="both be set"):
            Author(user_email="x@example.com")


# [unit->REQ-STORE-AUTHOR-ID]
class TestAuthorSignature:
    """`signature_for` returns the right name/email for each scenario."""

    def test_engine_only_signature_is_default(
        self, repo: pygit2.Repository
    ) -> None:
        a = Author()
        sig = a.signature_for(repo)
        assert sig.name == ATTRACTOR_NAME
        assert sig.email == ATTRACTOR_EMAIL

    def test_configured_user_signature_uses_user(
        self, repo: pygit2.Repository
    ) -> None:
        a = Author(user_name="Jane", user_email="jane@example.com")
        sig = a.signature_for(repo)
        assert sig.name == "Jane"
        assert sig.email == "jane@example.com"


# [unit->REQ-STORE-AUTHOR-ID]
class TestAugmentCommitMessage:
    """`augment_commit_message` follows the §7.3 trailer rule."""

    def test_engine_only_no_trailer(self) -> None:
        a = Author()
        # No user → no Co-Authored-By trailer at all.
        out = a.augment_commit_message("checkpoint: foo")
        assert "Co-Authored-By" not in out

    def test_user_configured_adds_trailer(self) -> None:
        a = Author(user_name="Jane", user_email="jane@example.com")
        out = a.augment_commit_message("checkpoint: foo")
        # Trailer paragraph identifies the engine.
        assert "Co-Authored-By:" in out
        assert ATTRACTOR_NAME in out
        assert ATTRACTOR_EMAIL in out
