"""ORCH-073 FR-4 — .gitattributes: CHANGELOG.md merge=union.

Covers TC-11/TC-12 / AC-4. TC-11 asserts the repo-root .gitattributes declares the
union driver (git check-attr). TC-12 proves, in a throwaway git repo, that two
branches both editing '## [Unreleased]' merge WITHOUT a conflict and BOTH entries
survive — exactly what stops auto_rebase_onto_main from rolling a branch back.
"""

import subprocess
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[1]


def _git(cwd, *args, env=None):
    return subprocess.run(
        ["git", *args], cwd=str(cwd), capture_output=True, text=True, env=env,
    )


# ---------------------------------------------------------------------------
# TC-11 (AC-4): the repo-root .gitattributes declares CHANGELOG.md merge=union.
# ---------------------------------------------------------------------------
def test_tc11_gitattributes_declares_union():
    ga = REPO_ROOT / ".gitattributes"
    assert ga.is_file(), ".gitattributes must exist at the repo root"
    assert "CHANGELOG.md merge=union" in ga.read_text(encoding="utf-8")

    r = _git(REPO_ROOT, "check-attr", "merge", "CHANGELOG.md")
    assert r.returncode == 0, r.stderr
    # Output form: 'CHANGELOG.md: merge: union'
    assert "merge: union" in r.stdout, r.stdout


# ---------------------------------------------------------------------------
# TC-12 (AC-4): two Unreleased edits merge with no conflict; both kept.
# ---------------------------------------------------------------------------
def _init_repo(tmp_path):
    env = {
        "GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t",
        "GIT_COMMITTER_NAME": "t", "GIT_COMMITTER_EMAIL": "t@t",
        "GIT_CONFIG_GLOBAL": "/dev/null", "GIT_CONFIG_SYSTEM": "/dev/null",
        "PATH": __import__("os").environ.get("PATH", ""),
        "HOME": str(tmp_path),
    }
    repo = tmp_path / "repo"
    repo.mkdir()
    assert _git(repo, "init", "-b", "main", env=env).returncode == 0
    (repo / ".gitattributes").write_text("CHANGELOG.md merge=union\n", encoding="utf-8")
    base = (
        "# Changelog\n\n## [Unreleased]\n\n### Common\n\n## [0.1.0]\n- initial\n"
    )
    (repo / "CHANGELOG.md").write_text(base, encoding="utf-8")
    _git(repo, "add", ".", env=env)
    assert _git(repo, "commit", "-m", "base", env=env).returncode == 0
    return repo, env


def test_tc12_union_merge_keeps_both_entries(tmp_path):
    repo, env = _init_repo(tmp_path)

    # Branch A adds its Unreleased line.
    _git(repo, "checkout", "-b", "task-a", env=env)
    txt = (repo / "CHANGELOG.md").read_text(encoding="utf-8")
    (repo / "CHANGELOG.md").write_text(
        txt.replace("### Common\n", "### Common\n- ORCH-A: feature A\n"), encoding="utf-8"
    )
    _git(repo, "commit", "-am", "task A changelog", env=env)

    # Branch B (from main) adds a DIFFERENT Unreleased line at the same spot.
    _git(repo, "checkout", "main", env=env)
    _git(repo, "checkout", "-b", "task-b", env=env)
    txt = (repo / "CHANGELOG.md").read_text(encoding="utf-8")
    (repo / "CHANGELOG.md").write_text(
        txt.replace("### Common\n", "### Common\n- ORCH-B: feature B\n"), encoding="utf-8"
    )
    _git(repo, "commit", "-am", "task B changelog", env=env)

    # Merge A into B — union must avoid a conflict and keep BOTH lines.
    m = _git(repo, "merge", "--no-edit", "task-a", env=env)
    result = (repo / "CHANGELOG.md").read_text(encoding="utf-8")
    assert m.returncode == 0, f"union merge must not conflict: {m.stdout}\n{m.stderr}"
    assert "<<<<<<<" not in result and ">>>>>>>" not in result
    assert "ORCH-A: feature A" in result
    assert "ORCH-B: feature B" in result
