"""Unit tests for the bridge's `!testme` / `!testme --quick` trigger parser (WC7 + D1).

Pure: imports bridge/bridge.py (stdlib-only, no side effects at import — main() is __main__-guarded).
Locks the two accepted forms and the must-NOT-trigger cases the Adversary probes (`!testmexyz`, etc.).
"""

from __future__ import annotations

import os
import sys
from datetime import timedelta

# bridge.py reads HMAC/DRONE/GITEA secret FILES at import; point them at /dev/null (readable, empty)
# so the import works in a unit context — parse_trigger doesn't use any of them.
for _v in ("HMAC_FILE", "DRONE_TOKEN_FILE", "GITEA_TOKEN_FILE"):
    os.environ.setdefault(_v, "/dev/null")
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "bridge"))
import bridge  # noqa: E402


def test_plain_testme_is_cold():
    assert bridge.parse_trigger("!testme") == (True, False)
    assert bridge.parse_trigger("  !testme  ") == (True, False)  # trimmed


def test_quick_form():
    assert bridge.parse_trigger("!testme --quick") == (True, True)
    assert bridge.parse_trigger("  !testme --quick \n") == (True, True)


def test_non_trigger_forms_rejected():
    for body in (
        "!testmexyz",  # the Adversary's classic negative
        "!testme xyz",
        "!testme--quick",  # no space → not the quick form
        "!testme  --quick",  # double space → not an exact match (conservative)
        "please !testme",
        "testme",
        "",
        None,
    ):
        assert bridge.parse_trigger(body) == (False, False), body


# --- Phase 3 U3: YunoHost-style PR comment builders (R2) -----------------------------------------


def test_start_comment_is_yunohost_shaped():
    b = bridge.start_comment_body("uptime-kuma", "dfed87a39f8a", "https://drone.x/cc-ci/42")
    assert bridge.COMMENT_MARKER in b  # re-!testme updates the same comment
    assert "🌻" in b and "⏳" in b  # marker + in-progress
    assert "uptime-kuma" in b and "dfed87a3" in b
    assert "https://drone.x/cc-ci/42" in b


def test_result_comment_image_forward_when_card_available(monkeypatch):
    monkeypatch.setattr(bridge, "artifact_available", lambda url: True)
    monkeypatch.setattr(bridge, "DASH_URL", "https://ci.example")
    b = bridge.result_comment_body(
        "uptime-kuma", "dfed87a39f8a", "42", "https://drone.x/cc-ci/42", "success"
    )
    assert bridge.COMMENT_MARKER in b
    assert "✅" in b and "passed" in b
    # the card + badge are embedded as linked images at the stable /runs/<num>/ URLs
    assert "![cc-ci result card](https://ci.example/runs/42/summary.png)" in b
    assert "https://ci.example/runs/42/badge.svg" in b
    assert "(https://drone.x/cc-ci/42)" in b  # links to the run


def test_result_comment_text_fallback_when_card_missing(monkeypatch):
    # Render failed / not served → MUST degrade to text, never a broken image (R7).
    monkeypatch.setattr(bridge, "artifact_available", lambda url: False)
    b = bridge.result_comment_body(
        "hedgedoc", "abc1234def", "9", "https://drone.x/cc-ci/9", "failure"
    )
    assert "summary.png" not in b  # no image embed
    assert "![" not in b  # no markdown image at all
    assert "❌" in b and "failure" in b
    assert "https://drone.x/cc-ci/9" in b


def test_find_existing_comment_matches_marker(monkeypatch):
    monkeypatch.setattr(
        bridge,
        "list_comments",
        lambda fn, n: [
            {"id": 1, "body": "just a normal comment"},
            {"id": 2, "body": bridge.COMMENT_MARKER + "\n🌻 old run"},
        ],
    )
    assert bridge.find_existing_comment("org/repo", 5) == 2


def test_find_existing_comment_none_when_absent(monkeypatch):
    monkeypatch.setattr(bridge, "list_comments", lambda fn, n: [{"id": 1, "body": "hello"}])
    assert bridge.find_existing_comment("org/repo", 5) is None


def test_preexisting_comment_from_before_bridge_start_is_ignored():
    created = (bridge._PROCESS_STARTED_AT - timedelta(minutes=5)).isoformat().replace("+00:00", "Z")
    assert bridge._is_preexisting_comment({"created_at": created}) is True


def test_comment_after_bridge_start_is_not_treated_as_preexisting():
    created = (bridge._PROCESS_STARTED_AT + timedelta(minutes=5)).isoformat().replace("+00:00", "Z")
    assert bridge._is_preexisting_comment({"created_at": created}) is False
