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

//! Structured parameter types for RPC calls
//!
//! This module provides strongly-typed parameter structures to replace
//! dynamic JSON parameter construction and parsing throughout the RPC system.
//!
//! All parameter types have been consolidated into Request types in their respective message modules
//! and are re-exported here for backward compatibility.

// Re-export request types from their new locations in message modules
use serde::{Deserialize, Serialize};

pub use crate::messages::{
    get_account_info::GetAccountInfoRequest, get_balance::GetBalanceRequest,
    get_block::GetBlockRequest, get_connected_full_nodes::GetConnectedFullNodesRequest,
    get_epoch_info::GetEpochInfoRequest, get_fee_for_message::GetFeeForMessageRequest,
    get_health::GetHealthRequest,
    get_minimum_balance_for_rent_exemption::GetMinimumBalanceForRentExemptionRequest,
    get_multiple_accounts::GetMultipleAccountsRequest,
    get_signature_statuses::GetSignatureStatusesRequest,
    get_signatures_for_address::GetSignaturesForAddressRequest,
    get_subscription::GetSubscriptionRequest, get_transaction::GetTransactionRequest,
    get_transaction_count::GetTransactionCountRequest,
    get_triggered_transactions::GetTriggeredTransactionsRequest,
    get_validator_health::GetValidatorHealthRequest,
    get_workflow_lineage::GetWorkflowLineageRequest, is_blockhash_valid::IsBlockhashValidRequest,
    request_airdrop::RequestAirdropRequest, send_transaction::SendTransactionRequest,
};

/// Simple address parameter wrapper
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AddressParam {
    pub address: String,
}

impl AddressParam {
    pub fn new(address: String) -> Self {
        Self { address }
    }
}

#[cfg(test)]
mod tests {
    use serde_json::{from_value, json, to_value};

    use super::*;

    #[test]
    fn test_get_balance_request_serialization() {
        let request =
            GetBalanceRequest::new("84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string());
        let json = to_value(&request).unwrap();
        assert_eq!(
            json,
            json!({
                "address": "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri"
            })
        );

        let deserialized: GetBalanceRequest = from_value(json).unwrap();
        assert_eq!(deserialized, request);
    }

    #[test]
    fn test_get_account_info_request_serialization() {
        let request = GetAccountInfoRequest {
            address: "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            config: Some(crate::messages::get_account_info::GetAccountInfoConfig {
                data_slice: None,
                min_context_slot: None,
            }),
        };
        let json = to_value(&request).unwrap();

        let deserialized: GetAccountInfoRequest = from_value(json).unwrap();
        assert_eq!(deserialized.address, request.address);
    }

    #[test]
    fn test_request_airdrop_request_serialization() {
        let request = RequestAirdropRequest::new(
            "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri".to_string(),
            1000000000,
        );
        let json = to_value(&request).unwrap();
        assert_eq!(
            json,
            json!({"pubkey": "84astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDVcgri", "kelvins": 1000000000})
        );

        let deserialized: RequestAirdropRequest = from_value(json).unwrap();
        assert_eq!(deserialized, request);
    }

    #[test]
    fn test_get_signature_statuses_request_serialization() {
        let signatures = vec!["signature1".to_string(), "signature2".to_string()];
        let request = GetSignatureStatusesRequest {
            signatures: signatures.clone(),
            config: None,
        };
        let json = to_value(&request).unwrap();
        assert_eq!(json, json!({"signatures": signatures}));

        let deserialized: GetSignatureStatusesRequest = from_value(json).unwrap();
        assert_eq!(deserialized.signatures, request.signatures);
    }
}
