"""CLI argument and report helpers for migrate_repo_cloud_auth."""
import os
import subprocess
from pathlib import Path

import pytest
from scripts.migrate_repo_cloud_auth import (
    _commit_and_push,
    _needs_fix,
    _parse_user,
    _print_report,
    _validate_scope,
)
from src.domain.codegen.legacy_cloud_cutover import CutoverReport, ImportResult
from src.domain.codegen.legacy_user_store import RepoScan


def test_parse_user_requires_email():
    with pytest.raises(ValueError, match="email"):
        _parse_user("role=admin")
    user = _parse_user("email=Mohsin@Pie-Solutions.com,role=staff,name=Mohsin")
    assert user.email == "mohsin@pie-solutions.com"
    assert user.role == "admin"


def test_repo_override_requires_one_project():
    with pytest.raises(ValueError, match="--repo requires exactly one"):
        _validate_scope(project_ids=[], repo="/tmp/app", extra_users=[])
    with pytest.raises(ValueError, match="--repo requires exactly one"):
        _validate_scope(project_ids=["a", "b"], repo="/tmp/app", extra_users=[])
    _validate_scope(project_ids=["a"], repo="/tmp/app", extra_users=[])


def test_extra_users_require_one_project():
    with pytest.raises(ValueError, match="--user requires exactly one"):
        _validate_scope(project_ids=[], repo=None, extra_users=["email=a@b.com"])
    _validate_scope(project_ids=["a"], repo=None, extra_users=["email=a@b.com"])


def test_needs_fix_when_local_store_or_missing_adapter():
    empty = RepoScan([], [], [], [], True, True)
    dirty = RepoScan([], ["server/api/admin/users.ts"], [], [], False, False)
    ok = CutoverReport("1", "Demo", "nuxt_app", empty)
    broken = CutoverReport("1", "Demo", "nuxt_app", dirty)
    assert _needs_fix(ok) is False
    assert _needs_fix(broken) is True


def test_push_error_still_prints_completed_cutover(capsys):
    scan = RepoScan([], [], [], [], True, True)
    report = CutoverReport("1", "Demo", "nuxt_app", scan, dry_run=False)
    report.imported = [ImportResult("owner@example.com", "super_admin", "upserted")]
    report.adapter = {"written": ["server/api/admin/users.ts"], "backed_up": [], "skipped": []}
    _print_report(
        report,
        repo=Path("/tmp/app"),
        extra=[],
        mutating=True,
        error="git push failed: Authentication failed",
    )
    out = capsys.readouterr().out
    assert "[upserted] owner@example.com as super_admin" in out
    assert "ERROR: git push failed: Authentication failed" in out


@pytest.mark.asyncio
async def test_commit_and_push_refreshes_origin_and_pushes_existing_commit(monkeypatch):
    import tempfile

    pushed: list[tuple] = []

    async def fake_push(path, branch="main", *, force_with_lease=False):
        pushed.append((path, branch, force_with_lease))

    monkeypatch.setattr("src.workers.repo_ops.push_repo", fake_push)
    env = {
        **os.environ,
        "GIT_AUTHOR_NAME": "p2hs",
        "GIT_AUTHOR_EMAIL": "noreply@p2hs.com",
        "GIT_COMMITTER_NAME": "p2hs",
        "GIT_COMMITTER_EMAIL": "noreply@p2hs.com",
    }
    with tempfile.TemporaryDirectory() as raw:
        repo = Path(raw)
        def git(*arguments: str) -> None:
            subprocess.check_call(
                ["git", "-c", "init.defaultBranch=preview", *arguments],
                cwd=repo,
                env=env,
            )

        git("init")
        (repo / "README").write_text("ok", encoding="utf-8")
        git("add", ".")
        git("commit", "-m", "init")
        git("remote", "add", "origin", "https://github.com/P2HS/demo.git")
        result = await _commit_and_push(
            str(repo),
            "preview",
            push=True,
            adapter={"written": []},
            clone_url="https://x-access-token:tok@github.com/P2HS/demo.git",
        )
        url = subprocess.check_output(
            ["git", "remote", "get-url", "origin"], cwd=repo, text=True
        ).strip()
    assert result == "preview"
    assert url == "https://x-access-token:tok@github.com/P2HS/demo.git"
    assert pushed == [(str(repo), "preview", True)]
