//! SC-A + SC-B — Single-Apple-ID (solo) own-send exclusion and self-reply
//! resolution, end-to-end through the real orchestrator (both walls compose).
//!
//! ## Probe-provenance / two-wall contract
//!
//! On a single-Apple-ID (solo) account — the common case where the person
//! running CAR is also the approver, on their own iMessage account, with no
//! second device — both the daemon's outbound approval prompt AND the user's own
//! typed reply appear in the Mac's `chat.db` TWICE: once `is_from_me = 1` (the
//! sent / synced-sent copy) and once `is_from_me = 0` (a received self-echo).
//! The on-device probe confirmed the solo reply (`A0 approve` typed from the
//! user's iPhone) lands as an `is_from_me = 0` row in the `text` column.
//!
//! Own-send exclusion is a TWO-WALL architecture that already exists:
//!   * Wall 1 — the SQL filter `message.is_from_me = 0` (`read.rs`) drops every
//!     row the daemon authored before a row object is even constructed. Pinned
//!     at its own layer by the reader seam test (SC-D).
//!   * Wall 2 — `parse_inbound` is a closed grammar; the daemon's own multi-token
//!     bodies fall through to `InboundIntent::Ignore`. Pinned by the inline unit
//!     (SC-C).
//!
//! This test composes both walls at the orchestrator: it feeds the daemon's own
//! prompt echo (which the solo account would deliver `is_from_me = 0`) back
//! through `handle_inbound` and proves it is IGNORED (the approval stays Pending,
//! zero resolves, and it reached the parser exactly once), then feeds the user's
//! `A0 approve` reply and proves it RESOLVES exactly once. The harness builds
//! `InboundMessage` directly (it does not model `is_from_me`), so the rows here
//! stand in for what Wall 1 already kept — both an own-prompt echo and the user's
//! reply arrive `is_from_me = 0` on a solo account.
//!
//! Per scope-call C1 the test uses the standard harness handle and synthetic
//! monotonic rowids; only the load-bearing message *bodies* are literal (the
//! captured prompt echo body; the string `"A0 approve"`). NO literal probe phone
//! number / rowids appear in any assertion.

mod messaging_harness;
use messaging_harness::{extract_code, inbound, Harness, PAIRED};

#[tokio::test]
async fn own_send_echo_ignored_then_solo_reply_resolves() {
    let h = Harness::enabled_paired();
    let id = h.seed_fire_and_return("send wire transfer").await;

    // Outbound: the daemon mints the deterministic FIRST code `A0` and sends one
    // prompt. The spy captures the EXACT body the daemon authored.
    h.orch.observe_and_notify().await;
    let prompt_body = h.spy.calls()[0].1.clone();
    assert_eq!(
        extract_code(&prompt_body).as_deref(),
        Some("A0"),
        "the deterministic first-minted code is A0"
    );

    // --- SC-A: own-send echo IGNORED ---
    // Feed the captured prompt body back as the solo account's `is_from_me = 0`
    // self-echo (rowid 1). The sender IS the allowlisted paired handle, so it
    // passes the allowlist wall and reaches the parser — but Wall 2 (the closed
    // grammar) classifies the multi-token prompt as Ignore, so nothing resolves.
    h.orch
        .handle_inbound(&inbound(PAIRED, &prompt_body, 1))
        .await;

    assert!(
        !h.is_resolved(&id).await,
        "the daemon's own prompt echo must NOT resolve the approval — stays Pending"
    );
    assert_eq!(
        h.approval_resolved_count().await,
        0,
        "the echo produced ZERO resolves"
    );
    assert_eq!(
        h.orch.parse_call_count(),
        1,
        "the single allowlisted echo reached the parser exactly once (and was Ignored)"
    );

    // --- SC-B: solo self-reply RESOLVES ---
    // Next monotonic rowid: the user's genuine `A0 approve` reply (also arriving
    // `is_from_me = 0` on a solo account). The daemon distinguishes it from its
    // own echoed prompt and resolves the approval exactly once.
    h.orch
        .handle_inbound(&inbound(PAIRED, "A0 approve", 2))
        .await;

    assert!(
        h.is_resolved(&id).await,
        "the solo `A0 approve` reply resolves the approval"
    );
    assert_eq!(
        h.approval(&id).await.resolution.as_deref(),
        Some("approve"),
        "resolution string is exactly 'approve'"
    );
    assert_eq!(
        h.approval_resolved_count().await,
        1,
        "exactly one resolve — the genuine reply, after zero from the echo step"
    );
}
