use serde_json::{json, Value};
use sgclaw::browser::bridge_contract::{BridgeBrowserActionRequest, BridgeLifecycleCall};

#[test]
fn bridge_contract_names_match_documented_bridge_surface() {
    let lifecycle_names = [
        BridgeLifecycleCall::Connect.bridge_name(),
        BridgeLifecycleCall::Start.bridge_name(),
        BridgeLifecycleCall::Stop.bridge_name(),
        BridgeLifecycleCall::SubmitTask.bridge_name(),
    ];

    assert_eq!(
        lifecycle_names,
        [
            "sgclawConnect",
            "sgclawStart",
            "sgclawStop",
            "sgclawSubmitTask",
        ]
    );
}

#[test]
fn bridge_contract_represents_browser_action_requests_without_ws_business_frames() {
    let requests = vec![
        BridgeBrowserActionRequest::new(
            "navigate",
            json!({ "url": "https://www.baidu.com" }),
            "www.baidu.com",
        ),
        BridgeBrowserActionRequest::new(
            "click",
            json!({ "selector": "#submit" }),
            "www.zhihu.com",
        ),
        BridgeBrowserActionRequest::new(
            "getText",
            json!({ "selector": "#content" }),
            "www.zhihu.com",
        ),
    ];

    let serialized = serde_json::to_value(&requests).unwrap();
    let entries = serialized.as_array().unwrap();
    let actions = entries
        .iter()
        .map(|entry| entry["action"].as_str().unwrap())
        .collect::<Vec<_>>();

    assert_eq!(
        serialized,
        json!([
            {
                "action": "navigate",
                "params": { "url": "https://www.baidu.com" },
                "expected_domain": "www.baidu.com"
            },
            {
                "action": "click",
                "params": { "selector": "#submit" },
                "expected_domain": "www.zhihu.com"
            },
            {
                "action": "getText",
                "params": { "selector": "#content" },
                "expected_domain": "www.zhihu.com"
            }
        ])
    );
    assert_eq!(actions, vec!["navigate", "click", "getText"]);

    let first = entries.first().unwrap();
    let object = first.as_object().unwrap();
    assert_eq!(object.len(), 3);
    assert!(object.contains_key("action"));
    assert!(object.contains_key("params"));
    assert!(object.contains_key("expected_domain"));
    assert_eq!(first["expected_domain"], Value::String("www.baidu.com".to_string()));
}
