"""ORCH-016 / TC-13..TC-15: _post_usage_comments integration tests.

End-to-end (DB + filesystem worktree, no network) verification that
AgentLauncher._post_usage_comments:
  - resolves the task by (repo, branch),
  - threads the explicit duration_s into build_status_comment,
  - posts exactly ONE status comment authored by the finishing agent,
  - for deployer: ALSO posts the per-task usage summary (deployer authorship).

The actual Plane HTTP call (plane_sync.add_comment) is patched out; we only
check the (work_item_id, body, author) tuples the launcher passes to it.
"""

import os
import tempfile

os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")

_test_db = os.path.join(tempfile.gettempdir(), "test_orch016_post_usage.db")
os.environ["ORCH_DB_PATH"] = _test_db

import pytest  # noqa: E402

from src import db as db_module  # noqa: E402
from src.db import init_db, get_db  # noqa: E402
from src.agents.launcher import AgentLauncher  # noqa: E402


REPO = "enduro-trails"
BRANCH = "feature/ET-016-x"
WID = "ET-016"


@pytest.fixture
def setup_db(monkeypatch):
    monkeypatch.setattr(db_module.settings, "db_path", _test_db, raising=False)
    if os.path.exists(_test_db):
        os.unlink(_test_db)
    init_db()
    conn = get_db()
    conn.execute(
        "INSERT INTO tasks (id, repo, branch, stage, work_item_id) "
        "VALUES (1, ?, ?, 'review', ?)",
        (REPO, BRANCH, WID),
    )
    conn.commit()
    conn.close()
    yield
    if os.path.exists(_test_db):
        os.unlink(_test_db)


@pytest.fixture
def fake_worktree(monkeypatch, tmp_path):
    """Stub get_worktree_path inside the launcher module to a tmp_path location."""
    wt = tmp_path / "wt"
    (wt / "docs" / "work-items" / WID).mkdir(parents=True)

    def _get_wt(repo, branch):
        return str(wt)

    # The launcher imports get_worktree_path lazily inside the function body
    # (`from ..git_worktree import get_worktree_path`); patch the source module.
    monkeypatch.setattr("src.git_worktree.get_worktree_path", _get_wt)
    monkeypatch.setattr("src.usage._input_total", lambda u: 0)  # quiet <sub> tail
    return wt


@pytest.fixture
def capture_comments(monkeypatch):
    posts = []

    def _spy(work_item_id, body, author=None, **kwargs):
        posts.append({"wid": work_item_id, "body": body, "author": author})

    monkeypatch.setattr("src.agents.launcher.plane_add_comment", _spy)
    return posts


@pytest.fixture
def public_url(monkeypatch):
    from src.config import settings
    monkeypatch.setattr(
        settings, "gitea_public_url", "https://git.mva154.duckdns.org", raising=False
    )
    monkeypatch.setattr(settings, "gitea_url", "http://localhost:3000", raising=False)
    monkeypatch.setattr(settings, "gitea_owner", "admin", raising=False)


# ---------------------------------------------------------------------------
# TC-13: reviewer comment.
# ---------------------------------------------------------------------------
def test_tc13_reviewer_posts_one_status_comment(
    setup_db, fake_worktree, capture_comments, public_url
):
    (fake_worktree / "docs" / "work-items" / WID / "12-review.md").write_text(
        "---\nverdict: APPROVE\n---\nReviewed.",
    )

    AgentLauncher()._post_usage_comments(
        run_id=99, agent="reviewer", repo=REPO, branch=BRANCH,
        usage={"input_tokens": 1, "output_tokens": 1, "cost_usd": 0.01},
        duration_s=180,
    )

    assert len(capture_comments) == 1
    post = capture_comments[0]
    assert post["wid"] == WID
    assert post["author"] == "reviewer"
    body = post["body"]
    assert "\U0001f50e Reviewer" in body
    assert "Verdict: APPROVE" in body
    assert "Длительность: 3m 00s" in body
    assert "12-review.md" in body


# ---------------------------------------------------------------------------
# TC-14: tester comment.
# ---------------------------------------------------------------------------
def test_tc14_tester_posts_one_status_comment(
    setup_db, fake_worktree, capture_comments, public_url
):
    (fake_worktree / "docs" / "work-items" / WID / "13-test-report.md").write_text(
        "---\nverdict: PASS\n---\n",
    )

    AgentLauncher()._post_usage_comments(
        run_id=100, agent="tester", repo=REPO, branch=BRANCH,
        usage=None, duration_s=42,
    )

    assert len(capture_comments) == 1
    post = capture_comments[0]
    assert post["author"] == "tester"
    body = post["body"]
    assert "\U0001f9ea Tester" in body
    assert "Verdict: PASS" in body
    assert "Длительность: 42s" in body


# ---------------------------------------------------------------------------
# TC-15: deployer comment + per-task summary (two comments, both from deployer).
# ---------------------------------------------------------------------------
def test_tc15_deployer_posts_status_then_summary(
    setup_db, fake_worktree, capture_comments, public_url
):
    # Task stage = 'deploy' so build_status_comment uses 14-deploy-log.md.
    conn = get_db()
    conn.execute("UPDATE tasks SET stage='deploy' WHERE id=1")
    conn.commit()
    conn.close()
    (fake_worktree / "docs" / "work-items" / WID / "14-deploy-log.md").write_text(
        "---\ndeploy_status: SUCCESS\n---\nDeployed.",
    )

    AgentLauncher()._post_usage_comments(
        run_id=101, agent="deployer", repo=REPO, branch=BRANCH,
        usage={"input_tokens": 1, "output_tokens": 1, "cost_usd": 0.01},
        duration_s=300,
    )

    # 2 comments: status + per-task summary.
    assert len(capture_comments) == 2
    status, summary = capture_comments
    assert status["author"] == "deployer"
    assert "Status: SUCCESS" in status["body"]
    assert "Длительность: 5m 00s" in status["body"]
    assert "14-deploy-log.md" in status["body"]

    assert summary["author"] == "deployer"
    # task_summary_comment header (Russian "Итого по задаче").
    assert "\U0001f4ca" in summary["body"]
    assert "Итого" in summary["body"]


def test_deployer_staging_picks_15_log(
    setup_db, fake_worktree, capture_comments, public_url
):
    conn = get_db()
    conn.execute("UPDATE tasks SET stage='deploy-staging' WHERE id=1")
    conn.commit()
    conn.close()
    (fake_worktree / "docs" / "work-items" / WID / "15-staging-log.md").write_text(
        "---\nstaging_status: SUCCESS\n---\n",
    )

    AgentLauncher()._post_usage_comments(
        run_id=102, agent="deployer", repo=REPO, branch=BRANCH,
        usage=None, duration_s=10,
    )

    # deployer always also posts the summary; check the FIRST comment is status.
    assert len(capture_comments) == 2
    status = capture_comments[0]
    assert "Status: SUCCESS" in status["body"]
    assert "15-staging-log.md" in status["body"]
    assert "14-deploy-log.md" not in status["body"]
    assert "staging-деплой" in status["body"]
