/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public struct 'TemplateManager'. Replace with real documentation. (2025-12-30T22:23:21Z)
pub struct TemplateManager;

impl TemplateManager {
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'ensure_template'. Replace with real documentation. (2025-12-30T22:23:21Z)
    ///
    /// # Errors
    /// Returns `KamError` if the template is not found in built-in assets or local cache.
    pub fn ensure_template(template: &str) -> Result<(), KamError> {
        TemplateCacheManager::ensure_template(template)
    }

    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'list_builtin_templates'. Replace with real documentation. (2025-12-30T22:23:21Z)

    #[must_use]
    pub fn list_builtin_templates() -> Vec<String> {
        TemplateCacheManager::list_templates()
    }

    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'parse_template_vars'. Replace with real documentation. (2025-12-30T22:23:21Z)
    ///
    /// # Errors
    /// This function currently always returns `Ok`, but the signature allows for future error handling.
    pub fn parse_template_vars(vars: &[String]) -> Result<HashMap<String, String>, KamError> {
        TemplateVariableProcessor::parse_template_vars(vars)
    }

    /// Copy a template tree from `src` to `dst` performing variable substitution.
    ///
    /// Wrapper around `TemplateCopier::copy_and_replace`.
    ///
    /// # Errors
    /// - `KamError::InvalidDirectory` if `src` does not exist.
    /// - `KamError::Io` for filesystem errors.
    /// - `KamError::TemplateRenderError` when template rendering fails.
    pub fn copy_and_replace(
        src: &Path,
        dst: &Path,
        vars: &HashMap<String, String>,
        force: bool,
        template_id: &str,
    ) -> Result<(), KamError> {
        TemplateCopier::copy_and_replace(src, dst, vars, force, template_id)
    }

    /// Copy and render template files from `src` to `dst` with optional include/exclude rules.
    ///
    /// Wrapper around `TemplateCopier::copy_and_replace_with_rules`.
    ///
    /// # Errors
    /// - `KamError::InvalidDirectory` when `src` is invalid.
    /// - `KamError::Io` for filesystem failures.
    /// - `KamError::TemplateRenderError` for template rendering failures.
    pub fn copy_and_replace_with_rules(
        src: &Path,
        dst: &Path,
        vars: &HashMap<String, String>,
        force: bool,
        template_id: &str,
        excludes: Option<&[String]>,
        includes: Option<&[String]>,
    ) -> Result<(), KamError> {
        TemplateCopier::copy_and_replace_with_rules(
            src,
            dst,
            vars,
            force,
            template_id,
            excludes,
            includes,
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::errors::KamError;
    use std::collections::HashMap;
    use std::fs;
    use std::fs::File;
    use std::io::Write;
    use tempfile::tempdir;

    #[test]
    fn test_template_render_error_in_file() {
        let src_dir = tempdir().unwrap();
        let dst_dir = tempdir().unwrap();
        let src_path = src_dir.path().join("bad.tmpl");

        // Write a deliberately malformed template (unclosed brace) to trigger parse/render error.
        fs::write(&src_path, "{{ unclosed").unwrap();

        let vars: HashMap<String, String> = HashMap::new();
        let res = TemplateCopier::copy_and_replace_with_rules(
            src_dir.path(),
            dst_dir.path(),
            &vars,
            true,
            "test_template",
            None,
            None,
        );
        match res {
            Err(KamError::TemplateRenderError(_)) => (),
            Err(e) => panic!("expected TemplateRenderError, got {e:?}"),
            Ok(()) => panic!("expected error, got Ok"),
        }
    }

    // Filename render tests can be brittle because Tera often treats
    // brace-containing filenames as plain text or renders undefined variables
    // to empty strings. We already cover rendering error behavior in
    // `test_template_render_error_in_file` (malformed template content), which
    // exercises the same TemplateRenderError path. If filename-specific tests
    // are required in the future, add deterministic cases that reliably produce
    // a parse/render error (for example, by creating an actual malformed
    // template file and asserting the error), rather than relying on filename
    // parsing semantics which may vary across Tera versions.

    #[test]
    fn test_is_binary_detects_null_byte() {
        let tmp = tempdir().unwrap();
        let fpath = tmp.path().join("binfile");
        let mut f = File::create(&fpath).unwrap();
        f.write_all(&[0u8, 1, 2, 3]).unwrap();
        assert!(is_binary(&fpath));
    }
}
