use std::collections::BTreeMap;

use serde_json::value::Value as Json;

use crate::error::RenderError;
use crate::local_vars::LocalVars;

#[derive(Clone, Debug)]
pub enum BlockParamHolder {
    // a reference to certain context value
    Path(Vec<String>),
    // an actual value holder
    Value(Json),
}

impl BlockParamHolder {
    pub fn value(v: Json) -> BlockParamHolder {
        BlockParamHolder::Value(v)
    }

    pub fn path(r: Vec<String>) -> BlockParamHolder {
        BlockParamHolder::Path(r)
    }
}

/// A map holds block parameters. The parameter can be either a value or a reference
#[derive(Clone, Debug, Default)]
pub struct BlockParams<'reg> {
    data: BTreeMap<&'reg str, BlockParamHolder>,
}

impl<'reg> BlockParams<'reg> {
    /// Create a empty block parameter map.
    pub fn new() -> BlockParams<'reg> {
        BlockParams::default()
    }

    /// Add a path reference as the parameter. The `path` is a vector of path
    /// segments the relative to current block's base path.
    pub fn add_path(&mut self, k: &'reg str, path: Vec<String>) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::path(path));
        Ok(())
    }

    /// Add a value as parameter.
    pub fn add_value(&mut self, k: &'reg str, v: Json) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::value(v));
        Ok(())
    }

    /// Get a block parameter by its name.
    pub fn get(&self, k: &str) -> Option<&BlockParamHolder> {
        self.data.get(k)
    }
}

/// A data structure holds contextual data for current block scope.
#[derive(Debug, Clone, Default)]
pub struct BlockContext<'rc> {
    /// the base_path of current block scope
    base_path: Vec<String>,
    /// the base_value of current block scope, when the block is using a
    /// constant or derived value as block base
    base_value: Option<Json>,
    /// current block context variables
    block_params: BlockParams<'rc>,
    /// local variables in current context
    local_variables: LocalVars,
}

impl<'rc> BlockContext<'rc> {
    /// create a new `BlockContext` with default data
    pub fn new() -> BlockContext<'rc> {
        BlockContext::default()
    }

    /// set a local variable into current scope
    pub fn set_local_var(&mut self, name: &str, value: Json) {
        self.local_variables.put(name, value);
    }

    /// Get mutable access to the local variables
    pub fn local_variables_mut(&mut self) -> &mut LocalVars {
        &mut self.local_variables
    }

    /// get a local variable from current scope
    pub fn get_local_var(&self, name: &str) -> Option<&Json> {
        self.local_variables.get(name)
    }

    /// borrow a reference to current scope's base path
    /// all paths inside this block will be relative to this path
    pub fn base_path(&self) -> &Vec<String> {
        &self.base_path
    }

    /// borrow a mutable reference to the base path
    pub fn base_path_mut(&mut self) -> &mut Vec<String> {
        &mut self.base_path
    }

    /// borrow the base value
    pub fn base_value(&self) -> Option<&Json> {
        self.base_value.as_ref()
    }

    /// set the base value
    pub fn set_base_value(&mut self, value: Json) {
        self.base_value = Some(value);
    }

    /// Get a block parameter from this block.
    /// Block parameters needed to be supported by the block helper.
    /// The typical syntax for block parameter is:
    ///
    /// ```skip
    /// {{#myblock param1 as |block_param1|}}
    ///    ...
    /// {{/myblock}}
    /// ```
    ///
    pub fn get_block_param(&self, block_param_name: &str) -> Option<&BlockParamHolder> {
        self.block_params.get(block_param_name)
    }

    /// Set a block parameter into this block.
    pub fn set_block_params(&mut self, block_params: BlockParams<'rc>) {
        self.block_params = block_params;
    }
}
