use libremetaverse::GridClient;
use libremetaverse_lsl_tools::{Parser, YyParser};
use libremetaverse_rlv::{RlvActionCallbacksDefault, RlvRestrictionManager, RlvService};
use libremetaverse_types::compat::{CancellationToken, Guid, Subscription};
use libremetaverse_utilities::ConnectionManager;
use libremetaverse_voice_vivox::{TCPPipe, VoiceManager as VivoxVoiceManager};
use libremetaverse_voice_webrtc::{LibreMetaverseVoiceLogger, VoiceManager as WebRtcVoiceManager};

fn member_id<T>(result: Result<T, libremetaverse_types::Error>) -> &'static str {
    result
        .err()
        .expect("failure-only shim unexpectedly returned a value")
        .csharp_member()
        .expect("failure-only shim error")
}

async fn compile_rlv_calls(
    service: &RlvService,
    restrictions: &RlvRestrictionManager,
    sender_id: Guid,
    token: CancellationToken,
) {
    let _: Subscription = restrictions.subscribe_restriction_updated(None);
    let _ = service
        .process_message(String::new(), sender_id, String::new(), Some(token))
        .await;
}

fn compile_parser_call(parser: &Parser) {
    let _ = parser.parse_with_string(String::new());
}

async fn compile_utility_call(client: GridClient) {
    let _ = ConnectionManager::persistent_login(
        client,
        String::new(),
        String::new(),
        String::new(),
        String::new(),
        String::new(),
        String::new(),
    )
    .await;
}

fn compile_vivox_calls(manager: &VivoxVoiceManager, status: &mut i32) {
    let _: Subscription = manager.subscribe_on_login(None);
    let _ = manager.login(String::new(), String::new(), String::new(), status);
    let _ = manager.request_parcel_voice_info();
}

async fn compile_webrtc_calls(manager: &WebRtcVoiceManager) {
    let _: Subscription = manager.subscribe_on_group_voice_joined(None);
    let _ = manager.connect_primary_region().await;
    let _ = manager.request_parcel_voice_info().await;
}

#[test]
fn extension_flows_have_typed_callable_signatures() {
    let _ = compile_rlv_calls;
    let _ = compile_parser_call;
    let _ = compile_utility_call;
    let _ = compile_vivox_calls;
    let _ = compile_webrtc_calls;
}

#[test]
fn extension_constructors_fail_with_catalog_ids() {
    assert_eq!(
        member_id(YyParser::new()),
        "M:LibreMetaverse.LslTools.YyParser.#ctor"
    );
    assert_eq!(
        member_id(RlvActionCallbacksDefault::new()),
        "M:LibreMetaverse.RLV.RlvActionCallbacksDefault.#ctor"
    );
    assert_eq!(
        member_id(TCPPipe::new()),
        "M:LibreMetaverse.Voice.Vivox.TCPPipe.#ctor"
    );
    assert_eq!(
        member_id(LibreMetaverseVoiceLogger::new()),
        "M:LibreMetaverse.Voice.WebRTC.LibreMetaverseVoiceLogger.#ctor"
    );
}
