use crate::{AssetId, CandidAssetId};
use candid::{CandidType, Deserialize};
use ex3_serde::bincode;
use ic_stable_structures::storable::Bound;
use ic_stable_structures::Storable;
use serde::Serialize;

pub mod meme_market;
pub mod spot_market;

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MarketIdentifier {
    /// Base asset id
    pub base_asset_id: AssetId,

    /// Quote asset id
    pub quote_asset_id: AssetId,
}

#[derive(CandidType, Clone, Debug, Eq, PartialEq, Deserialize, PartialOrd, Ord, Hash)]
pub struct CandidMarketIdentifier {
    /// Base asset id
    pub base_asset_id: CandidAssetId,

    /// Quote asset id
    pub quote_asset_id: CandidAssetId,
}

impl Storable for MarketIdentifier {
    fn to_bytes(&self) -> std::borrow::Cow<[u8]> {
        bincode::serialize(self).unwrap().into()
    }

    fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self {
        bincode::deserialize(bytes.as_ref()).unwrap()
    }

    const BOUND: Bound = Bound::Bounded {
        max_size: 64,
        is_fixed_size: false,
    };
}

impl From<CandidMarketIdentifier> for MarketIdentifier {
    fn from(candid_market_identifier: CandidMarketIdentifier) -> Self {
        MarketIdentifier {
            base_asset_id: candid_market_identifier.base_asset_id.into(),
            quote_asset_id: candid_market_identifier.quote_asset_id.into(),
        }
    }
}

impl From<MarketIdentifier> for CandidMarketIdentifier {
    fn from(market_identifier: MarketIdentifier) -> Self {
        CandidMarketIdentifier {
            base_asset_id: market_identifier.base_asset_id.into(),
            quote_asset_id: market_identifier.quote_asset_id.into(),
        }
    }
}
