// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Test for the new structured RPC error handling

use rialo_cdk::error::{RialoError, RpcErrorDetails};

#[test]
fn test_rpc_error_details_display() {
    // Test with full error details (status, code, message)
    // Display only shows the message, but fields are accessible
    let error_with_status =
        RpcErrorDetails::new(Some(422), -32002, "Transaction is too large".to_string());

    let display_str = format!("{error_with_status}");
    assert_eq!(display_str, "Transaction is too large");
    // Verify fields are accessible for debugging
    assert_eq!(error_with_status.status, Some(422));
    assert_eq!(error_with_status.code, -32002);

    // Test with code but no status
    let error_with_code =
        RpcErrorDetails::new(None, -32002, "Transaction is too large".to_string());

    let display_str = format!("{error_with_code}");
    assert_eq!(display_str, "Transaction is too large");
    assert_eq!(error_with_code.status, None);
    assert_eq!(error_with_code.code, -32002);

    // Test with just message (backwards compatibility)
    let error_message_only = RpcErrorDetails::from_message("Simple error message".to_string());

    let display_str = format!("{error_message_only}");
    assert_eq!(display_str, "Simple error message");
    assert_eq!(error_message_only.status, None);
    assert_eq!(error_message_only.code, 0);
}

#[test]
fn test_rialo_error_rpc_display() {
    // Test RialoError::Rpc with structured details
    // Display shows "RPC error: {message}" for clean output
    let error_details =
        RpcErrorDetails::new(Some(422), -32002, "Transaction is too large".to_string());

    let rpc_error = RialoError::Rpc(error_details.clone());
    let display_str = format!("{rpc_error}");

    assert!(display_str.starts_with("RPC error:"));
    assert!(display_str.contains("Transaction is too large"));
    // Verify structured details are accessible via the error
    if let RialoError::Rpc(details) = rpc_error {
        assert_eq!(details.status, Some(422));
        assert_eq!(details.code, -32002);
    }
}

#[test]
fn test_example_422_error_format() {
    // Test the specific error format from the user's example:
    // "RPC request failed with status: 422 Unprocessable Entity => {"jsonrpc":"2.0","error":{"code":-32002,"message":"Transaction is too large"},"id":null}"

    let error_details =
        RpcErrorDetails::new(Some(422), -32002, "Transaction is too large".to_string());

    let rpc_error = RialoError::Rpc(error_details.clone());
    let error_string = format!("{rpc_error}");

    // The format should be clean and readable: "RPC error: {message}"
    assert!(error_string.contains("RPC error:"));
    assert!(error_string.contains("Transaction is too large"));

    // Structured details are available via the error object, not in display string
    assert_eq!(error_details.status, Some(422));
    assert_eq!(error_details.code, -32002);

    // Should be cleaner than the old format
    assert!(!error_string.contains("RPC request failed with status:"));
    assert!(!error_string.contains("=>"));
}
