use ex3_serde::{bincode, cbor};

use crate::market::meme_market::{MemeMarketTradingFee, MemeMarketTradingSettings};

use crate::market::MarketIdentifier;
use crate::transaction::{
    MemeMarketRegistration, UpdateMemeMarketFeeTo, UpdateMemeMarketInitialFeeTo,
    UpdateMemeMarketInitialTradingFee, UpdateMemeMarketTradingFee, UpdateMemeMarketTradingSettings,
};
use crate::{MemeMarketId, WalletRegisterId};

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

    // bincode
    let bytes = bincode::serialize(&update_market_fee_to).unwrap();
    let update_market_fee_to_deserialized: UpdateMemeMarketFeeTo =
        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: UpdateMemeMarketFeeTo =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee_to, update_market_fee_to_deserialized);
}

#[test]
fn test_register_market_serde() {
    let register_market = MemeMarketRegistration {
        identifier: MarketIdentifier {
            base_asset_id: 1u32.into(),
            quote_asset_id: 2u32.into(),
        },
        base_asset_quantity: 100u32.into(),
        quote_asset_quantity: 200u32.into(),
    };

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

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

#[test]
fn test_update_market_settings_serde() {
    let update_market_settings = UpdateMemeMarketTradingSettings {
        market_id: MemeMarketId::from(1u32),
        trading_settings: MemeMarketTradingSettings {
            price_max_decimal: 8,
            volume_max_decimal: 8,
            min_order_amount: 100u32.into(),
            min_order_volume: 100u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_market_settings).unwrap();
    let update_market_settings_deserialized: UpdateMemeMarketTradingSettings =
        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: UpdateMemeMarketTradingSettings =
        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 = UpdateMemeMarketInitialFeeTo {
        fee_to: WalletRegisterId::from(100u32),
    };

    // bincode
    let bytes = bincode::serialize(&update_global_market_fee_to).unwrap();
    let update_global_market_fee_to_deserialized: UpdateMemeMarketInitialFeeTo =
        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: UpdateMemeMarketInitialFeeTo =
        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 = UpdateMemeMarketInitialTradingFee {
        fee: MemeMarketTradingFee {
            limit_order_fee: 100u32.into(),
            fee_decimal: 8,
            bonding_curve_fee_taking_ratio: 300u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_global_market_fee).unwrap();
    let update_global_market_fee_deserialized: UpdateMemeMarketInitialTradingFee =
        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: UpdateMemeMarketInitialTradingFee =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(
        update_global_market_fee,
        update_global_market_fee_deserialized
    );
}

#[test]
fn test_update_meme_market_init_trading_settings() {
    let update_meme_market_init_trading_settings = UpdateMemeMarketTradingSettings {
        market_id: MemeMarketId::from(1u32),
        trading_settings: MemeMarketTradingSettings {
            price_max_decimal: 8,
            volume_max_decimal: 8,
            min_order_amount: 100u32.into(),
            min_order_volume: 100u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_meme_market_init_trading_settings).unwrap();
    let update_meme_market_init_trading_settings_deserialized: UpdateMemeMarketTradingSettings =
        bincode::deserialize(&bytes).unwrap();
    assert_eq!(
        update_meme_market_init_trading_settings,
        update_meme_market_init_trading_settings_deserialized
    );

    // cbor
    let bytes = cbor::serialize(&update_meme_market_init_trading_settings).unwrap();
    let update_meme_market_init_trading_settings_deserialized: UpdateMemeMarketTradingSettings =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(
        update_meme_market_init_trading_settings,
        update_meme_market_init_trading_settings_deserialized
    );
}

#[test]
fn test_update_market_fee_serde() {
    let update_market_fee = UpdateMemeMarketTradingFee {
        market_id: MemeMarketId::from(1u32),
        fee: MemeMarketTradingFee {
            limit_order_fee: 100u32.into(),
            fee_decimal: 8,
            bonding_curve_fee_taking_ratio: 300u32.into(),
        },
    };

    // bincode
    let bytes = bincode::serialize(&update_market_fee).unwrap();
    let update_market_fee_deserialized: UpdateMemeMarketTradingFee =
        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: UpdateMemeMarketTradingFee =
        cbor::deserialize(&bytes).unwrap();
    assert_eq!(update_market_fee, update_market_fee_deserialized);
}
