//! Integration tests for ACP transport layer.
//!
//! These tests verify both stdio and HTTP transport implementations work correctly.

use dirigent_core::acp::transport::{
    JsonRpcError, JsonRpcErrorResponse, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse,
    JsonRpcResult, TransportError, TransportState,
};

/// Test JSON-RPC request creation and serialization.
#[test]
fn test_jsonrpc_request() {
    let req = JsonRpcRequest::new(
        1,
        "test_method",
        Some(serde_json::json!({"param1": "value1"})),
    );

    assert_eq!(req.jsonrpc, "2.0");
    assert_eq!(req.id, serde_json::Value::Number(1.into()));
    assert_eq!(req.method, "test_method");

    let json = serde_json::to_string(&req).unwrap();
    assert!(json.contains("\"jsonrpc\":\"2.0\""));
    assert!(json.contains("\"id\":1"));
    assert!(json.contains("\"method\":\"test_method\""));
    assert!(json.contains("\"param1\":\"value1\""));
}

/// Test JSON-RPC notification creation and serialization.
#[test]
fn test_jsonrpc_notification() {
    let notif = JsonRpcNotification::new(
        "test_notification",
        Some(serde_json::json!({"data": "test"})),
    );

    assert_eq!(notif.jsonrpc, "2.0");
    assert_eq!(notif.method, "test_notification");

    let json = serde_json::to_string(&notif).unwrap();
    assert!(json.contains("\"jsonrpc\":\"2.0\""));
    assert!(json.contains("\"method\":\"test_notification\""));
    // Notifications don't have an "id" field
    assert!(!json.contains("\"id\""));
}

/// Test JSON-RPC response deserialization.
#[test]
fn test_jsonrpc_response_deserialization() {
    let json = r#"{"jsonrpc":"2.0","id":1,"result":{"status":"ok"}}"#;
    let response: JsonRpcResponse = serde_json::from_str(json).unwrap();

    assert_eq!(response.jsonrpc, "2.0");
    assert_eq!(response.id, serde_json::Value::Number(1.into()));
    assert_eq!(response.result.get("status").unwrap(), "ok");
}

/// Test JSON-RPC error response deserialization.
#[test]
fn test_jsonrpc_error_response_deserialization() {
    let json = r#"{"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"Invalid Request"}}"#;
    let error_response: JsonRpcErrorResponse = serde_json::from_str(json).unwrap();

    assert_eq!(error_response.jsonrpc, "2.0");
    assert_eq!(error_response.id, serde_json::Value::Number(1.into()));
    assert_eq!(error_response.error.code, -32600);
    assert_eq!(error_response.error.message, "Invalid Request");
}

/// Test JsonRpcResult helper methods.
#[test]
fn test_jsonrpc_result_helpers() {
    // Test success result
    let success_response = JsonRpcResponse {
        jsonrpc: "2.0".to_string(),
        id: serde_json::Value::Number(1.into()),
        result: serde_json::json!({"status": "ok"}),
    };
    let result = JsonRpcResult::Success(success_response);

    assert!(result.is_success());
    assert!(!result.is_error());
    assert!(result.result().is_some());
    assert!(result.error().is_none());
    assert_eq!(result.result().unwrap().get("status").unwrap(), "ok");

    // Test error result
    let error_response = JsonRpcErrorResponse {
        jsonrpc: "2.0".to_string(),
        id: serde_json::Value::Number(2.into()),
        error: JsonRpcError {
            code: -32600,
            message: "Invalid Request".to_string(),
            data: None,
        },
    };
    let result = JsonRpcResult::Error(error_response);

    assert!(!result.is_success());
    assert!(result.is_error());
    assert!(result.result().is_none());
    assert!(result.error().is_some());
    assert_eq!(result.error().unwrap().code, -32600);
}

/// Test JsonRpcResult conversion to Result.
#[test]
fn test_jsonrpc_result_into_result() {
    // Success case
    let success_response = JsonRpcResponse {
        jsonrpc: "2.0".to_string(),
        id: serde_json::Value::Number(1.into()),
        result: serde_json::json!({"status": "ok"}),
    };
    let result = JsonRpcResult::Success(success_response);
    let converted = result.into_result();
    assert!(converted.is_ok());

    // Error case
    let error_response = JsonRpcErrorResponse {
        jsonrpc: "2.0".to_string(),
        id: serde_json::Value::Number(2.into()),
        error: JsonRpcError {
            code: -32600,
            message: "Invalid Request".to_string(),
            data: None,
        },
    };
    let result = JsonRpcResult::Error(error_response);
    let converted = result.into_result();
    assert!(converted.is_err());

    match converted {
        Err(TransportError::JsonRpcError(error)) => {
            assert_eq!(error.code, -32600);
            assert_eq!(error.message, "Invalid Request");
        }
        _ => panic!("Expected JsonRpcError"),
    }
}

/// Test transport state enum.
#[test]
fn test_transport_state() {
    assert_eq!(TransportState::Disconnected, TransportState::Disconnected);
    assert_ne!(TransportState::Connected, TransportState::Disconnected);

    let state = TransportState::Connecting;
    assert!(matches!(state, TransportState::Connecting));
}

// Note: SSE event extraction is tested in http.rs unit tests
