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

use rialo_s_sdk::transaction::TransactionError;
use serde::{Deserialize, Serialize};
use validator::Validate;

use super::rpc_response_context::RpcResponseContext;

/// Request parameters for the `getSignatureStatuses` RPC method
#[derive(Debug, Deserialize, Serialize, Clone, Validate)]
pub struct GetSignatureStatusesRequest {
    /// Protocol version for forward compatibility.
    #[serde(default)]
    #[validate(custom(function = crate::validation::validate_protocol_version))]
    pub version: u16,
    /// Array of transaction signatures to query (base58-encoded)
    #[validate(length(max = 256, message = "Maximum of 256 signatures allowed"))]
    #[validate(custom(function = crate::validation::validate_signatures))]
    pub signatures: Vec<String>,

    /// Extra options for the signature status search.
    /// NOTE: This parameter is unused; it's present only for Solana compatibility.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub config: Option<GetSignatureStatusesConfig>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct GetSignatureStatusesConfig {
    /// Indicates whether the node should consult the ledger cache
    /// in search of a signature status.
    pub search_transaction_history: bool,
}

/// The 'inner' response message for a GetSignatureStatuses request.
#[derive(Serialize, Deserialize)]
pub struct GetSignatureStatusesResponse {
    /// Protocol version for forward compatibility.
    #[serde(default)]
    pub version: u16,
    pub context: RpcResponseContext,
    pub value: Vec<GetIndividualSignatureStatus>,
}

impl GetSignatureStatusesResponse {
    pub fn new(version: u16, value: Vec<GetIndividualSignatureStatus>, slot: u64) -> Self {
        Self {
            version,
            context: RpcResponseContext::new(slot),
            value,
        }
    }
}

/// The status of a single signature.
/// This is a part of the GetSignatureStatuses response and complies with the Solana specification.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct GetIndividualSignatureStatus {
    /// The slot in which the transaction was processed.
    pub slot: u64,
    /// None if the transaction succeeded.
    pub err: Option<TransactionError>,
    /// Indicates whether the transaction has been executed.
    pub executed: bool,
}
