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

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

pub struct DirHelper {
    site: String,
    dir: DynDir,
}

impl DirHelper {
    pub fn new(site: &str, dir: DynDir) -> Self {
        Self {
            site: site.to_owned(),
            dir,
        }
    }
}

impl HelperDef for DirHelper {
    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 url = vfs::url(&self.site, &self.dir, vpath)
                .ok_or_else(|| RenderError::new("path is not anchored anywhere"))?;
            Ok(ScopedJson::Derived(Value::String(url)))
        } else {
            Err(RenderError::new("missing path string"))
        }
    }
}
