//! Network response test fixtures
//!
//! Provides mock HTTP and WebSocket responses for testing.

use serde_json::json;

/// Mock HTTP response builder
pub struct MockHttpResponse {
    status: u16,
    body: String,
    headers: Vec<(String, String)>,
}

impl MockHttpResponse {
    pub fn new() -> Self {
        Self {
            status: 200,
            body: String::new(),
            headers: Vec::new(),
        }
    }

    pub fn status(mut self, status: u16) -> Self {
        self.status = status;
        self
    }

    pub fn json_body(mut self, body: serde_json::Value) -> Self {
        self.body = body.to_string();
        self.headers.push((
            "Content-Type".to_string(),
            "application/json".to_string(),
        ));
        self
    }

    pub fn header(mut self, key: &str, value: &str) -> Self {
        self.headers.push((key.to_string(), value.to_string()));
        self
    }

    pub fn build(self) -> (u16, String, Vec<(String, String)>) {
        (self.status, self.body, self.headers)
    }
}

impl Default for MockHttpResponse {
    fn default() -> Self {
        Self::new()
    }
}

/// Generate mock API responses
pub fn mock_market_data_response() -> serde_json::Value {
    json!({
        "symbol": "AAPL",
        "timestamp": "2024-01-15T10:30:00Z",
        "open": 150.00,
        "high": 152.50,
        "low": 149.75,
        "close": 151.25,
        "volume": 1000000
    })
}

pub fn mock_order_response() -> serde_json::Value {
    json!({
        "order_id": "ord_123456",
        "symbol": "AAPL",
        "quantity": 100,
        "price": 150.00,
        "side": "buy",
        "status": "filled",
        "filled_quantity": 100,
        "average_fill_price": 150.00
    })
}

pub fn mock_error_response(code: u16, message: &str) -> serde_json::Value {
    json!({
        "error": {
            "code": code,
            "message": message
        }
    })
}

/// WebSocket message fixtures
pub fn mock_websocket_trade_message() -> String {
    json!({
        "type": "trade",
        "symbol": "AAPL",
        "price": 150.00,
        "size": 100,
        "timestamp": "2024-01-15T10:30:00Z"
    })
    .to_string()
}

pub fn mock_websocket_quote_message() -> String {
    json!({
        "type": "quote",
        "symbol": "AAPL",
        "bid": 149.95,
        "ask": 150.05,
        "bid_size": 500,
        "ask_size": 300,
        "timestamp": "2024-01-15T10:30:00Z"
    })
    .to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_http_response_builder() {
        let (status, body, headers) = MockHttpResponse::new()
            .status(201)
            .json_body(json!({"success": true}))
            .header("X-Custom", "value")
            .build();

        assert_eq!(status, 201);
        assert!(body.contains("success"));
        assert_eq!(headers.len(), 2); // Content-Type + X-Custom
    }

    #[test]
    fn test_mock_responses() {
        let market_data = mock_market_data_response();
        assert_eq!(market_data["symbol"], "AAPL");

        let order = mock_order_response();
        assert_eq!(order["status"], "filled");

        let error = mock_error_response(404, "Not found");
        assert_eq!(error["error"]["code"], 404);
    }
}
