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

//! Integration tests for validation pipeline

#[cfg(test)]
mod tests {
    use crate::{
        messages::{
            get_signatures_for_address::{
                GetSignaturesForAddressConfig, GetSignaturesForAddressRequest,
            },
            get_workflow_lineage::GetWorkflowLineageRequest,
            request_airdrop::RequestAirdropRequest,
        },
        validation::{validate_request, ValidationError},
    };

    #[test]
    fn test_complete_validation_pipeline_request_airdrop() {
        // Test valid request
        let valid_request = RequestAirdropRequest {
            pubkey: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            kelvins: 1000000000, // 1 RLO
        };

        let result = validate_request(valid_request);
        assert!(result.is_ok());

        // Test invalid pubkey
        let invalid_pubkey_request = RequestAirdropRequest {
            pubkey: "invalid_pubkey".to_string(),
            kelvins: 1000000000,
        };

        let result = validate_request(invalid_pubkey_request);
        assert!(result.is_err());

        // Test zero kelvins
        let zero_kelvins_request = RequestAirdropRequest {
            pubkey: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            kelvins: 0,
        };

        let result = validate_request(zero_kelvins_request);
        assert!(result.is_err());

        // Test excessive kelvins
        let excessive_kelvins_request = RequestAirdropRequest {
            pubkey: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            kelvins: 2_000_000_000_000_000_000, // Exceeds maximum
        };

        let result = validate_request(excessive_kelvins_request);
        assert!(result.is_err());
    }

    #[test]
    fn test_complete_validation_pipeline_get_signatures_for_address() {
        // Test valid request
        let valid_request = GetSignaturesForAddressRequest {
            address: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            config: Some(GetSignaturesForAddressConfig {
                limit: Some(100),
                before: None,
                until: None,
            }),
        };

        let result = validate_request(valid_request);
        assert!(result.is_ok());

        // Test invalid address
        let invalid_address_request = GetSignaturesForAddressRequest {
            address: "invalid_address".to_string(),
            config: None,
        };

        let result = validate_request(invalid_address_request);
        assert!(result.is_err());

        // Test invalid limit in config
        let invalid_limit_request = GetSignaturesForAddressRequest {
            address: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            config: Some(GetSignaturesForAddressConfig {
                limit: Some(1001), // Exceeds maximum
                before: None,
                until: None,
            }),
        };

        let result = validate_request(invalid_limit_request);
        assert!(result.is_err());

        // Test zero limit in config
        let zero_limit_request = GetSignaturesForAddressRequest {
            address: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            config: Some(GetSignaturesForAddressConfig {
                limit: Some(0), // Invalid: zero
                before: None,
                until: None,
            }),
        };

        let result = validate_request(zero_limit_request);
        assert!(result.is_err());
    }

    #[test]
    fn test_complete_validation_pipeline_get_workflow_lineage() {
        // Test valid request
        let valid_request = GetWorkflowLineageRequest {
            signature: "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW".to_string(),
            max_depth: Some(10),
            include_events: Some(true),
        };

        let result = validate_request(valid_request);
        assert!(result.is_ok());

        // Test empty signature
        let empty_signature_request = GetWorkflowLineageRequest {
            signature: "".to_string(),
            max_depth: Some(10),
            include_events: Some(true),
        };

        let result = validate_request(empty_signature_request);
        assert!(result.is_err());

        // Test invalid signature
        let invalid_signature_request = GetWorkflowLineageRequest {
            signature: "invalid_signature".to_string(),
            max_depth: Some(10),
            include_events: Some(true),
        };

        let result = validate_request(invalid_signature_request);
        assert!(result.is_err());

        // Test excessive max_depth
        let excessive_depth_request = GetWorkflowLineageRequest {
            signature: "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW".to_string(),
            max_depth: Some(200), // Exceeds maximum of 100
            include_events: Some(true),
        };

        let result = validate_request(excessive_depth_request);
        assert!(result.is_err());

        // Test zero max_depth (should be valid but might be flagged as invalid by validation)
        let zero_depth_request = GetWorkflowLineageRequest {
            signature: "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW".to_string(),
            max_depth: Some(0), // Invalid: below minimum of 1
            include_events: Some(true),
        };

        let result = validate_request(zero_depth_request);
        assert!(result.is_err());
    }

    #[test]
    fn test_validation_error_messages() {
        // Test that validation errors contain meaningful messages
        let invalid_request = RequestAirdropRequest {
            pubkey: "invalid".to_string(),
            kelvins: 0,
        };

        match validate_request(invalid_request) {
            Err(ValidationError::InvalidFormat(msg)) | Err(ValidationError::Multiple(msg)) => {
                // Should contain information about the validation failure
                assert!(!msg.is_empty());
            }
            Err(e) => {
                // Other validation error types are also acceptable
                assert!(!e.to_string().is_empty());
            }
            Ok(_) => {
                panic!("Expected validation error but got success");
            }
        }
    }

    #[test]
    fn test_validation_preserves_valid_data() {
        // Test that validation doesn't modify valid data
        let original_request = RequestAirdropRequest {
            pubkey: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            kelvins: 1000000000,
        };

        let original_pubkey = original_request.pubkey.clone();
        let original_kelvins = original_request.kelvins;

        let validated_request = validate_request(original_request).unwrap();

        assert_eq!(validated_request.pubkey, original_pubkey);
        assert_eq!(validated_request.kelvins, original_kelvins);
    }
}
