// UI contract for the Recover Upstream audio controls.
//
// Scope: source-level assertions around the launcher recovery rail and button
// actions. This avoids opening a real GTK session while still protecting copy,
// labels, tooltips, and RPC routing.
// Targets: `client/src/launcher/ui_components/build_operations_rail.rs` and
// `client/src/launcher/ui/utility_button_bindings.rs`.
// Why: operators need the button that fixed the stale Google Meet epoch to say
// exactly what it does, and it must not be confused with USB or video recovery.

const OPERATIONS_RAIL_SRC: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/launcher/ui_components/build_operations_rail.rs"
));
const UTILITY_BINDINGS_SRC: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/launcher/ui/utility_button_bindings.rs"
));

#[test]
fn recover_audio_button_is_labeled_as_audio_under_recover_upstream() {
    for marker in [
        "let recovery_heading = gtk::Label::new(Some(\"Recover\\nUpstream\"));",
        "let uac_recover_button = rail_button(",
        "\"Audio\",",
        "retire the stale upstream audio epoch",
        "bundled mic+camera reconnect without resetting USB or changing calibration",
    ] {
        assert!(
            OPERATIONS_RAIL_SRC.contains(marker),
            "Recover Audio UI should preserve marker {marker}"
        );
    }

    assert!(
        !OPERATIONS_RAIL_SRC.contains("\"Heal A/V\""),
        "the old label implied video/calibration mutation and should stay retired"
    );
}

#[test]
fn recover_audio_click_routes_to_uac_only_and_explains_side_effects() {
    let audio_start = UTILITY_BINDINGS_SRC
        .find("widgets.uac_recover_button.connect_clicked")
        .expect("audio recovery binding should exist");
    let video_start = UTILITY_BINDINGS_SRC
        .find("widgets.uvc_recover_button.connect_clicked")
        .expect("video recovery binding should follow audio recovery");
    let audio_block = &UTILITY_BINDINGS_SRC[audio_start..video_start];

    for marker in [
        "Recover Audio 1/3: retiring the stale upstream audio epoch cleanly",
        "recover_uac_soft(&server_addr)",
        "Recover Audio 2/3: old epoch released",
        "bundled media will reconnect without resetting USB or calibration",
    ] {
        assert!(
            audio_block.contains(marker),
            "Recover Audio action should preserve marker {marker}"
        );
    }

    assert!(!audio_block.contains("recover_usb_soft"));
    assert!(!audio_block.contains("recover_uvc_soft"));
    assert!(!audio_block.contains("reset_usb"));
}
