use serde::{Deserialize, Serialize};

use crate::{Result, Timestamp};

#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SymbolId(pub u32);

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct SymbolInfo {
    pub id: SymbolId,
    pub ticker: String,
    pub asset_class: AssetClass,
    pub exchange: String,
    pub base_currency: String,
    pub quote_currency: String,
    pub tick_size: f64,
    pub lot_size: f64,
    pub margin_required: Option<f64>,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum AssetClass {
    CryptoSpot,
    CryptoPerpetual,
    CryptoFuture,
    Equity,
    EquityOption,
    Future,
    Forex,
    Index,
    Custom,
}

pub trait SymbolRegistry: Send + Sync {
    fn resolve(&self, provider: &str, raw_symbol: &str, date: Timestamp) -> Result<SymbolId>;

    fn info(&self, id: SymbolId) -> Result<&SymbolInfo>;

    fn all_symbols(&self) -> &[SymbolInfo];
}
