use ex3_serde::{bincode, cbor};

use crate::market::{
    SpotMarketIdentifier, SpotMarketTradingFee, SpotMarketTradingSettings, SpotOrderPriceLimitation,
};
use crate::transaction::{
    SpotMarketRegistration, UpdateSpotMarketFeeTo, UpdateSpotMarketInitialFeeTo,
    UpdateSpotMarketInitialTradingFee, UpdateSpotMarketTradingFee, UpdateSpotMarketTradingSettings,
};
use crate::{SpotMarketId, WalletRegisterId};

#[test]
fn test_update_market_fee_to_serde() {
    let update_market_fee_to = UpdateSpotMarketFeeTo {
        market_id: SpotMarketId::from(1u32),
        fee_to: WalletRegisterId::from(1u32),
    };

    // bincode
    let bytes = bincode::serialize(&update_market_fee_to).unwrap();
    let update_market_fee_to_deserialized: UpdateSpotMarketFeeTo =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee_to, update_market_fee_to_deserialized);

    // cbor
    let bytes = cbor::serialize(&update_market_fee_to).unwrap();
    let update_market_fee_to_deserialized: UpdateSpotMarketFeeTo =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee_to, update_market_fee_to_deserialized);
}

#[test]
fn test_register_market_serde() {
    let register_market = SpotMarketRegistration {
        identifier: SpotMarketIdentifier {
            base_asset_id: 1u32.into(),
            quote_asset_id: 2u32.into(),
        },
        base_asset_quantity: 100u32.into(),
        quote_asset_quantity: 200u32.into(),
        trading_settings: SpotMarketTradingSettings {
            price_max_decimal: 8,
            volume_max_decimal: 8,
            min_order_amount: 300u32.into(),
            min_order_volume: 400u32.into(),
            price_limitation: SpotOrderPriceLimitation {
                bid_price_rate_cap: 100u32.into(),
                ask_price_rate_floor: 100u32.into(),
                rate_decimal: 8,
            },
        },
    };

    // bincode
    let bytes = bincode::serialize(&register_market).unwrap();
    let register_market_deserialized: SpotMarketRegistration =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(register_market, register_market_deserialized);

    // cbor
    let bytes = cbor::serialize(&register_market).unwrap();
    let register_market_deserialized: SpotMarketRegistration = cbor::deserialize(&bytes).unwrap();
    assert_eq!(register_market, register_market_deserialized);
}

#[test]
fn test_update_market_settings_serde() {
    let update_market_settings = UpdateSpotMarketTradingSettings {
        market_id: SpotMarketId::from(1u32),
        trading_settings: SpotMarketTradingSettings {
            price_max_decimal: 8,
            volume_max_decimal: 8,
            min_order_amount: 100u32.into(),
            min_order_volume: 100u32.into(),
            price_limitation: SpotOrderPriceLimitation {
                bid_price_rate_cap: 100u32.into(),
                ask_price_rate_floor: 100u32.into(),
                rate_decimal: 8,
            },
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_market_settings).unwrap();
    let update_market_settings_deserialized: UpdateSpotMarketTradingSettings =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(update_market_settings, update_market_settings_deserialized);

    // cbor
    let bytes = cbor::serialize(&update_market_settings).unwrap();
    let update_market_settings_deserialized: UpdateSpotMarketTradingSettings =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(update_market_settings, update_market_settings_deserialized);
}

#[test]
fn test_update_global_market_fee_to_serde() {
    let update_global_market_fee_to = UpdateSpotMarketInitialFeeTo {
        fee_to: WalletRegisterId::from(1u32),
    };

    // bincode
    let bytes = bincode::serialize(&update_global_market_fee_to).unwrap();
    let update_global_market_fee_to_deserialized: UpdateSpotMarketInitialFeeTo =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(
        update_global_market_fee_to,
        update_global_market_fee_to_deserialized
    );

    // cbor
    let bytes = cbor::serialize(&update_global_market_fee_to).unwrap();
    let update_global_market_fee_to_deserialized: UpdateSpotMarketInitialFeeTo =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(
        update_global_market_fee_to,
        update_global_market_fee_to_deserialized
    );
}

#[test]
fn test_update_global_market_fee_serde() {
    let update_global_market_fee = UpdateSpotMarketInitialTradingFee {
        fee: SpotMarketTradingFee {
            taker_fee: 100u32.into(),
            maker_fee: 200u32.into(),
            fee_decimal: 8,
            amm_v2_fee_taking_ratio: 300u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_global_market_fee).unwrap();
    let update_global_market_fee_deserialized: UpdateSpotMarketInitialTradingFee =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(
        update_global_market_fee,
        update_global_market_fee_deserialized
    );

    // cbor
    let bytes = cbor::serialize(&update_global_market_fee).unwrap();
    let update_global_market_fee_deserialized: UpdateSpotMarketInitialTradingFee =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(
        update_global_market_fee,
        update_global_market_fee_deserialized
    );
}

#[test]
fn test_update_market_fee_serde() {
    let update_market_fee = UpdateSpotMarketTradingFee {
        market_id: SpotMarketId::from(1u32),
        fee: SpotMarketTradingFee {
            taker_fee: 100u32.into(),
            maker_fee: 200u32.into(),
            fee_decimal: 8,
            amm_v2_fee_taking_ratio: 200u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_market_fee).unwrap();
    let update_market_fee_deserialized: UpdateSpotMarketTradingFee =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee, update_market_fee_deserialized);

    // cbor
    let bytes = cbor::serialize(&update_market_fee).unwrap();
    let update_market_fee_deserialized: UpdateSpotMarketTradingFee =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee, update_market_fee_deserialized);
}
