//! # Generated Protobuf Types
//!
//! This module exposes the generated Protocol Buffer types and gRPC service
//! definitions compiled from `proto/otc/rfq/v1/*.proto`.
//!
//! # Structure
//!
//! The generated code includes:
//! - **Common types**: `Uuid`, `Decimal`, `Timestamp`, `OrderSide`, `RfqState`, etc.
//! - **Domain messages**: `Rfq`, `Quote`, `Trade`, `Instrument`
//! - **Service messages**: Request/Response types for all RPC methods
//! - **gRPC service**: `RfqService` trait and client/server implementations
//!
//! # Usage
//!
//! ```ignore
//! use otc_rfq::api::grpc::proto::{
//!     rfq_service_server::{RfqService, RfqServiceServer},
//!     CreateRfqRequest, CreateRfqResponse, Rfq,
//! };
//! ```

/// Generated protobuf types for OTC RFQ v1 API.
///
/// This module is generated by `tonic-build` from the proto files in
/// `proto/otc/rfq/v1/`. It includes all message types, enums, and the
/// `RfqService` gRPC service definition.
pub mod otc_rfq_v1 {
    #![allow(missing_docs)]
    #![allow(clippy::all)]
    #![allow(clippy::pedantic)]
    #![allow(clippy::nursery)]
    #![allow(clippy::clone_on_ref_ptr)]
    tonic::include_proto!("otc.rfq.v1");
}

// Re-export commonly used types at module level for convenience
pub use otc_rfq_v1::*;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn order_side_values() {
        assert_eq!(OrderSide::Unspecified as i32, 0);
        assert_eq!(OrderSide::Buy as i32, 1);
        assert_eq!(OrderSide::Sell as i32, 2);
    }

    #[test]
    fn rfq_state_values() {
        assert_eq!(RfqState::Unspecified as i32, 0);
        assert_eq!(RfqState::Created as i32, 1);
        assert_eq!(RfqState::QuoteRequesting as i32, 2);
        assert_eq!(RfqState::QuotesReceived as i32, 3);
        assert_eq!(RfqState::ClientSelecting as i32, 4);
        assert_eq!(RfqState::Executing as i32, 5);
        assert_eq!(RfqState::Executed as i32, 6);
        assert_eq!(RfqState::Failed as i32, 7);
        assert_eq!(RfqState::Cancelled as i32, 8);
        assert_eq!(RfqState::Expired as i32, 9);
    }

    #[test]
    fn venue_type_values() {
        assert_eq!(VenueType::Unspecified as i32, 0);
        assert_eq!(VenueType::InternalMm as i32, 1);
        assert_eq!(VenueType::ExternalMm as i32, 2);
        assert_eq!(VenueType::DexAggregator as i32, 3);
        assert_eq!(VenueType::Protocol as i32, 4);
        assert_eq!(VenueType::RfqProtocol as i32, 5);
    }

    #[test]
    fn asset_class_values() {
        assert_eq!(AssetClass::Unspecified as i32, 0);
        assert_eq!(AssetClass::CryptoSpot as i32, 1);
        assert_eq!(AssetClass::CryptoDerivs as i32, 2);
        assert_eq!(AssetClass::Stock as i32, 3);
        assert_eq!(AssetClass::Forex as i32, 4);
        assert_eq!(AssetClass::Commodity as i32, 5);
    }

    #[test]
    fn uuid_message_creation() {
        let uuid = Uuid {
            value: "550e8400-e29b-41d4-a716-446655440000".to_string(),
        };
        assert!(!uuid.value.is_empty());
    }

    #[test]
    fn decimal_message_creation() {
        let decimal = Decimal {
            value: "123.456789".to_string(),
        };
        assert_eq!(decimal.value, "123.456789");
    }

    #[test]
    fn timestamp_message_creation() {
        let ts = Timestamp {
            seconds: 1704067200,
            nanos: 500_000_000,
        };
        assert_eq!(ts.seconds, 1704067200);
        assert_eq!(ts.nanos, 500_000_000);
    }

    #[test]
    fn instrument_message_creation() {
        let instrument = Instrument {
            symbol: "BTC/USD".to_string(),
            asset_class: AssetClass::CryptoSpot as i32,
            base_asset: "BTC".to_string(),
            quote_asset: "USD".to_string(),
        };
        assert_eq!(instrument.symbol, "BTC/USD");
        assert_eq!(instrument.base_asset, "BTC");
        assert_eq!(instrument.quote_asset, "USD");
    }

    #[test]
    fn error_details_message_creation() {
        let mut metadata = std::collections::HashMap::new();
        metadata.insert("field".to_string(), "quantity".to_string());

        let error = ErrorDetails {
            code: 400,
            message: "Invalid quantity".to_string(),
            metadata,
        };
        assert_eq!(error.code, 400);
        assert!(error.metadata.contains_key("field"));
    }

    #[test]
    fn create_rfq_request_creation() {
        let request = CreateRfqRequest {
            client_id: "client-123".to_string(),
            instrument: Some(Instrument {
                symbol: "ETH/USD".to_string(),
                asset_class: AssetClass::CryptoSpot as i32,
                base_asset: "ETH".to_string(),
                quote_asset: "USD".to_string(),
            }),
            side: OrderSide::Buy as i32,
            quantity: Some(Decimal {
                value: "10.5".to_string(),
            }),
            timeout_seconds: 300,
        };
        assert_eq!(request.client_id, "client-123");
        assert!(request.instrument.is_some());
        assert_eq!(request.side, OrderSide::Buy as i32);
    }

    #[test]
    fn quote_message_creation() {
        let quote = Quote {
            id: Some(Uuid {
                value: "quote-id".to_string(),
            }),
            rfq_id: Some(Uuid {
                value: "rfq-id".to_string(),
            }),
            venue_id: "venue-1".to_string(),
            venue_type: VenueType::ExternalMm as i32,
            price: Some(Decimal {
                value: "50000.00".to_string(),
            }),
            quantity: Some(Decimal {
                value: "1.0".to_string(),
            }),
            commission: Some(Decimal {
                value: "0.001".to_string(),
            }),
            valid_until: None,
            created_at: None,
        };
        assert_eq!(quote.venue_id, "venue-1");
        assert!(quote.price.is_some());
    }

    #[test]
    fn trade_message_creation() {
        let trade = Trade {
            id: Some(Uuid {
                value: "trade-id".to_string(),
            }),
            rfq_id: Some(Uuid {
                value: "rfq-id".to_string(),
            }),
            quote_id: Some(Uuid {
                value: "quote-id".to_string(),
            }),
            venue_id: "venue-1".to_string(),
            price: Some(Decimal {
                value: "50000.00".to_string(),
            }),
            quantity: Some(Decimal {
                value: "1.0".to_string(),
            }),
            venue_execution_ref: "exec-ref-123".to_string(),
            created_at: None,
        };
        assert_eq!(trade.venue_execution_ref, "exec-ref-123");
    }

    #[test]
    fn rfq_message_creation() {
        let rfq = Rfq {
            id: Some(Uuid {
                value: "rfq-id".to_string(),
            }),
            client_id: "client-123".to_string(),
            instrument: Some(Instrument {
                symbol: "BTC/USD".to_string(),
                asset_class: AssetClass::CryptoSpot as i32,
                base_asset: "BTC".to_string(),
                quote_asset: "USD".to_string(),
            }),
            side: OrderSide::Buy as i32,
            quantity: Some(Decimal {
                value: "1.0".to_string(),
            }),
            state: RfqState::Created as i32,
            expires_at: None,
            quotes: vec![],
            selected_quote_id: None,
            created_at: None,
            updated_at: None,
        };
        assert_eq!(rfq.client_id, "client-123");
        assert_eq!(rfq.state, RfqState::Created as i32);
    }
}
