use std::fmt::Display;

use const_oid::{db::DB, ObjectIdentifier};

use crate::{
    value::{FromValue, StringOrStringSet, ToStringOrStringSet},
    CDatabase,
};

#[derive(Debug, Eq, PartialEq)]
pub struct Oid(ObjectIdentifier);

impl FromValue for Oid {
    fn from_value_opt(value: &crate::cache::Value) -> crate::ntds::Result<Option<Self>>
    where
        Self: Sized,
    {
        match value {
            crate::cache::Value::Text(s) => Ok(Some(Self(ObjectIdentifier::new(s)?))),
            v => {
                log::error!("I don't know how to extract OIDs from {v:?}");
                Ok(None)
            }
        }
    }
}

impl Display for Oid {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match DB.by_oid(&self.0) {
            Some(s) => write!(f, "{s} ({})", self.0),
            None => self.0.fmt(f),
        }
    }
}

impl ToStringOrStringSet for Oid {
    fn to_string_or_stringset(&self, _database: &CDatabase<'_, '_>) -> StringOrStringSet {
        StringOrStringSet::String(self.to_string())
    }
}
