use handlebars::{Context, Handlebars, Helper, HelperDef, RenderContext, RenderError, ScopedJson};
use serde_json::Value;

use crate::vfs::{self, Content, DynDir, VPath};

pub struct IncludeStaticHelper {
    dir: DynDir,
}

impl IncludeStaticHelper {
    pub fn new(dir: DynDir) -> Self {
        Self { dir }
    }
}

impl HelperDef for IncludeStaticHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Handlebars<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        if let Some(path) = h.param(0).and_then(|v| v.value().as_str()) {
            let vpath = VPath::try_new(path).map_err(|e| RenderError::new(e.to_string()))?;
            let content = vfs::query::<Content>(&self.dir, vpath)
                .ok_or_else(|| RenderError::new("file does not exist"))?
                .string()
                .map_err(|_| RenderError::new("included file does not contain UTF-8 text"))?;
            Ok(ScopedJson::Derived(Value::String(content)))
        } else {
            Err(RenderError::new("missing path string"))
        }
    }
}
