mod common;

use std::sync::Arc;
use std::time::Duration;

use common::MockTransport;
use sgclaw::agent::handle_browser_message;
use sgclaw::pipe::{Action, AgentMessage, BrowserMessage, BrowserPipeTool, Timing};
use sgclaw::security::MacPolicy;

fn test_policy() -> MacPolicy {
    MacPolicy::from_json_str(
        r#"{
            "version": "1.0",
            "domains": { "allowed": ["oa.example.com", "www.baidu.com"] },
            "pipe_actions": {
                "allowed": ["click", "type", "navigate", "getText"],
                "blocked": ["eval", "executeJsInPage"]
            }
        }"#,
    )
    .unwrap()
}

#[test]
fn submit_task_sends_three_commands_and_finishes_with_task_complete() {
    let transport = Arc::new(MockTransport::new(vec![
        BrowserMessage::Response {
            seq: 1,
            success: true,
            data: serde_json::json!({ "navigated": true }),
            aom_snapshot: vec![],
            timing: Timing {
                queue_ms: 1,
                exec_ms: 20,
            },
        },
        BrowserMessage::Response {
            seq: 2,
            success: true,
            data: serde_json::json!({ "typed": true }),
            aom_snapshot: vec![],
            timing: Timing {
                queue_ms: 1,
                exec_ms: 20,
            },
        },
        BrowserMessage::Response {
            seq: 3,
            success: true,
            data: serde_json::json!({ "clicked": true }),
            aom_snapshot: vec![],
            timing: Timing {
                queue_ms: 1,
                exec_ms: 20,
            },
        },
    ]));
    let tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    handle_browser_message(
        transport.as_ref(),
        &tool,
        BrowserMessage::SubmitTask {
            instruction: "打开百度搜索天气".to_string(),
        },
    )
    .unwrap();

    let sent = transport.sent_messages();

    assert_eq!(sent.len(), 7);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.baidu.com"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "type 天气 into #kw"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, .. }
            if *seq == 2 && action == &Action::Type
    ));
    assert!(matches!(
        &sent[4],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click #su"
    ));
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, .. }
            if *seq == 3 && action == &Action::Click
    ));
    assert!(matches!(
        &sent[6],
        AgentMessage::TaskComplete { success, summary }
            if *success && summary == "已在百度搜索天气"
    ));
}
