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

//! This crate contains basic types used by Rialo network.
//! When a type is referenced by multiple crates, it is a
//! good idea to have it in crate for simpler dependency management.
//!
//! This crate now includes REX-specific types with TEE attestation support.

/// Transaction validity window in milliseconds.
///
/// A transaction is valid from its `valid_from` timestamp until `valid_from + TRANSACTION_VALIDITY_WINDOW_SECS`.
/// This value is used by both the consensus layer (to filter invalid transactions before proposal)
/// and the execution layer (to reject transactions during processing).
///
/// The value of 120 seconds (2 minutes) provides a reasonable window for:
/// - Client clock drift tolerance
/// - Network propagation delays
/// - Transaction retry attempts
pub const TRANSACTION_VALIDITY_WINDOW_MS: u64 = 120 * 1000;

/// A random seed value derived from consensus.
///
/// This is a newtype wrapper around `u64` that provides type safety for random seed values
/// used in block execution and transaction processing.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct RandomSeed(pub [u8; 32]);

impl From<[u8; 32]> for RandomSeed {
    fn from(value: [u8; 32]) -> Self {
        Self(value)
    }
}

impl From<u64> for RandomSeed {
    fn from(value: u64) -> Self {
        Self((0..4).fold([0u8; 32], |mut acc, i| {
            acc[i * 8..(i + 1) * 8].copy_from_slice(&value.to_le_bytes());
            acc
        }))
    }
}

impl From<RandomSeed> for u64 {
    fn from(seed: RandomSeed) -> Self {
        u64::from_be_bytes(seed.0[0..8].try_into().expect("to succeed"))
    }
}

// Admin transaction types (only available in non-pdk builds)
#[cfg(feature = "non-pdk")]
pub mod admin;

// Transaction validity utilities (only available in non-pdk builds)
#[cfg(feature = "non-pdk")]
pub mod validity;

// Consensus cryptographic types (only available in non-pdk builds)
#[cfg(feature = "non-pdk")]
pub mod consensus_crypto;

// Core cryptographic types
pub mod crypto;

pub mod headers;
pub mod http_filter;
#[cfg(test)]
mod http_filter_tests;
#[cfg(feature = "non-pdk")]
pub mod multiaddr;
pub mod nonce;
#[cfg(test)]
mod nonce_tests;
mod prelude;
pub mod shared_rpc_types;
pub mod transaction_execution_results;

// REX-specific modules
pub mod attestation;
pub mod duties;
pub mod duty_config;
pub mod error;
pub mod modified_entries;
pub mod output;
pub mod rex;
pub mod rex_info;
pub mod tee_types;
#[cfg(test)]
mod tests;
pub mod websocket;
pub mod websocket_op;

// Re-export REX types
// Re-export admin types (only available in non-pdk builds)
#[cfg(feature = "non-pdk")]
pub use admin::{
    AdminTransaction, Blake3Hash, EpochChangeConfig, EpochConsensusConfig, EpochIdentifier,
    HandoverCertificate, ValidatorInfo, ValidatorReadyMessage, BLAKE3_HASH_SIZE,
    BLS12381_PUBLIC_KEY_SIZE, ED25519_PUBLIC_KEY_SIZE, READY_MESSAGE_SIGNING_SIZE,
};
// Re-export consensus crypto types (only available in non-pdk builds)
#[cfg(feature = "non-pdk")]
pub use attestation::{ed25519_keypair_to_pubkey_slice, ed25519_signature_to_slice};
pub use attestation::{
    AttestationReport, AttestationReportInner, VerificationError, VerifiedAttestation,
};
#[cfg(feature = "non-pdk")]
pub use consensus_crypto::{
    AuthorityPublicKey, NetworkKeyPair, NetworkPrivateKey, NetworkPublicKey, ProtocolKeyPair,
    ProtocolKeySignature, ProtocolPublicKey,
};
// Re-export crypto types
pub use crypto::{PublicKey, TeeUserData, TEE_USER_DATA_SIZE, X25519_KEY_SIZE};
pub use duties::{AuthorityKeyBytes, RexDutiesMap, RexDutiesMapKey, RexDutiesMapValue};
pub use duty_config::*;
pub use error::*;
pub use modified_entries::*;
// Re-export multiaddr types
#[cfg(feature = "non-pdk")]
pub use multiaddr::{Multiaddr, Protocol};
pub use output::*;
/// Re-export for convenience
pub use prelude::*;
pub use rex_info::*;
pub use tee_types::{
    parse_evidence, AttestationEvidence, AwsSevSnpEvidenceData, AzureSevSnpEvidenceData,
    SevSnpEvidenceData, TeeEvidenceError, TeeType,
};
pub use websocket_op::*;

/// A wrapper enum to distinguish different types of messages processed in consensus.
#[cfg(feature = "non-pdk")]
#[derive(serde::Deserialize, serde::Serialize)]
pub enum ConsensusMessage {
    RexUpdateResult(Box<RexUpdateResult>),
    VersionedTransaction(rialo_s_sdk::transaction::VersionedTransaction),
    /// Admin transactions for privileged operations like epoch changes.
    AdminTransaction(Box<AdminTransaction>),
}

// Re-export validity functions for convenience
// Re-export test helpers when testing feature is enabled
#[cfg(feature = "testing")]
pub use validity::{
    create_admin_transaction, create_rex_update_with_target_timestamp,
    create_versioned_transaction_with_timestamp,
};
#[cfg(feature = "non-pdk")]
pub use validity::{
    extract_valid_from, extract_valid_until, is_expired, is_not_yet_valid, is_too_far_in_future,
    MAX_FUTURE_VALID_FROM_MS,
};
