Skip to content
use std::fmt::Display;

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
pub struct NamespaceTree {
    pub namespaces: Vec<NamespaceNode>,
}

impl Display for NamespaceTree {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        for namespace in &self.namespaces {
            writeln!(f, "{}", namespace)?;
        }
        Ok(())
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct NamespaceNode {
    pub name: String,
    pub repositories: Vec<String>,
}

impl Display for NamespaceNode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "{}", self.name)?;
        Ok(())
    }
}

impl NamespaceNode {
    pub fn example() -> Self {
        Self {
            name: "example".to_string(),
            repositories: vec!["TestRepo".to_string()],
        }
    }
}

impl NamespaceTree {
    pub fn example() -> Self {
        Self {
            namespaces: vec![NamespaceNode::example()],
        }
    }
}

pub fn example_tree() -> NamespaceTree {
    NamespaceTree::example()
}

#[cfg(feature = "testing")]
fn fake_bytes() -> Vec<u8> {
    let tree = NamespaceTree::example();
    rmp_serde::to_vec(&tree).unwrap()
}

#[cfg(feature = "testing")]
pub async fn tree_from_remote(_url: &str) -> NamespaceTree {
    let bytes = fake_bytes();
    rmp_serde::from_slice(&bytes).expect("not working in testing mode")
}

#[cfg(not(feature = "testing"))]
pub async fn tree_from_remote(url: &str) -> NamespaceTree {
    let response = reqwest::get(url).await.expect("could not reach remote");
    let bytes = response
        .bytes()
        .await
        .expect("could not read response")
        .to_vec();

    rmp_serde::from_slice(&bytes).expect("could not decode response")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_tree_from_remote() {
        let tree = NamespaceTree::example();
        assert_eq!(tree.namespaces.len(), 1);
        assert_eq!(tree.namespaces[0].name, "example");
    }
}