use crate::authentication::Authentication;
use async_trait::async_trait;
use std::time::{Duration, Instant};
use url::Url;

type BoxedError = Box<dyn std::error::Error>;

#[derive(Default, Clone)]
pub struct DummyAuth {
    auth_value: Option<String>,
    valid_until: Option<Instant>,
}

#[allow(dead_code)]
impl DummyAuth {
    pub fn new() -> Self {
        DummyAuth {
            auth_value: None,
            valid_until: None,
        }
    }
}

#[async_trait]
impl Authentication for DummyAuth {
    async fn authenticate(
        &mut self,
        _client_identity: &str,
        _client_secret: &str,
        _base_url: &Url,
        _reqwest_client: &reqwest::Client,
    ) -> Result<String, BoxedError> {
        if let Some(auth_value) = &self.auth_value {
            // We have a value - is it valid still
            if let Some(validity) = self.valid_until {
                if validity > Instant::now() {
                    return Ok(auth_value.to_string());
                }
            }
        }

        //re-auth
        self.auth_value = Some("This is a dummy token that expires in 30 seconds".into());
        self.valid_until = Some(Instant::now() + Duration::from_secs(30));
        Ok(self.auth_value.as_ref().unwrap().to_string())
    }
}
