use crate::api::Credentials;
use crate::api::JwtToken;
use async_trait::async_trait;

#[async_trait]
pub trait AuthenticationStore {
    async fn get_credentials(&mut self) -> Option<Credentials>;
    async fn get_token(&mut self) -> Option<String>;
    async fn set_token(&mut self, token: String);
}

pub struct InMemoryAuthenticationStore {
    credentials: Option<Credentials>,
    token: Option<JwtToken>,
}

impl Default for InMemoryAuthenticationStore {
    fn default() -> Self {
        Self::new(None)
    }
}

impl InMemoryAuthenticationStore {
    pub fn new(credentials: Option<Credentials>) -> Self {
        Self {
            credentials,
            token: None,
        }
    }
}

#[async_trait]
impl AuthenticationStore for InMemoryAuthenticationStore {
    async fn get_credentials(&mut self) -> Option<Credentials> {
        self.credentials.clone()
    }

    async fn get_token(&mut self) -> Option<String> {
        self.token.clone().map(|token| token.to_string())
    }

    async fn set_token(&mut self, token: String) {
        self.token = Some(JwtToken::new(&token).unwrap());
    }
}
