use crate::domain::MarkdownRenderer;
use crate::infrastructure::file_repository;

pub fn render_string(renderer: &dyn MarkdownRenderer, content: &str) -> String {
    renderer.render(content)
}

pub fn render_file(renderer: &dyn MarkdownRenderer, path: &str) -> Result<String, String> {
    let content = file_repository::read_file(path)?;
    Ok(renderer.render(&content))
}

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

    struct MockRenderer;

    impl MarkdownRenderer for MockRenderer {
        fn render(&self, content: &str) -> String {
            format!("<mock>{content}</mock>")
        }
    }

    #[test]
    fn render_string_delegates_to_renderer() {
        let renderer = MockRenderer;
        let result = render_string(&renderer, "hello");
        assert_eq!(result, "<mock>hello</mock>");
    }

    #[test]
    fn render_string_empty_content() {
        let renderer = MockRenderer;
        let result = render_string(&renderer, "");
        assert_eq!(result, "<mock></mock>");
    }

    #[test]
    fn render_file_success() {
        let dir = std::env::temp_dir().join("pena_rs_render_file");
        fs::create_dir_all(&dir).unwrap();
        let file = dir.join("test.md");
        fs::write(&file, "world").unwrap();
        let renderer = MockRenderer;
        let result = render_file(&renderer, file.to_str().unwrap());
        fs::remove_dir_all(&dir).unwrap();
        assert_eq!(result.unwrap(), "<mock>world</mock>");
    }

    #[test]
    fn render_file_not_found() {
        let renderer = MockRenderer;
        let result = render_file(&renderer, "/nonexistent/pena_rs_file.md");
        assert!(result.is_err());
    }
}
