use std::collections::{HashMap, VecDeque};
use std::convert::From;
use std::iter::Peekable;
use std::str::FromStr;

use pest::error::LineColLocation;
use pest::iterators::Pair;
use pest::{Parser, Position, Span};
use serde_json::value::Value as Json;

use crate::error::{TemplateError, TemplateErrorReason};
use crate::grammar::{self, HandlebarsParser, Rule};
use crate::json::path::{parse_json_path_from_iter, Path};

use self::TemplateElement::*;

#[derive(PartialEq, Clone, Debug)]
pub struct TemplateMapping(pub usize, pub usize);

/// A handlebars template
#[derive(PartialEq, Clone, Debug, Default)]
pub struct Template {
    pub name: Option<String>,
    pub elements: Vec<TemplateElement>,
    pub mapping: Vec<TemplateMapping>,
}

#[derive(Default)]
pub(crate) struct TemplateOptions {
    pub(crate) prevent_indent: bool,
    pub(crate) name: Option<String>,
}

impl TemplateOptions {
    fn name(&self) -> String {
        self.name
            .as_ref()
            .cloned()
            .unwrap_or_else(|| "Unnamed".to_owned())
    }
}

#[derive(PartialEq, Clone, Debug)]
pub struct Subexpression {
    // we use box here avoid resursive struct definition
    pub element: Box<TemplateElement>,
}

impl Subexpression {
    pub fn new(
        name: Parameter,
        params: Vec<Parameter>,
        hash: HashMap<String, Parameter>,
    ) -> Subexpression {
        Subexpression {
            element: Box::new(Expression(Box::new(HelperTemplate {
                name,
                params,
                hash,
                template: None,
                inverse: None,
                block_param: None,
                block: false,
            }))),
        }
    }

    pub fn is_helper(&self) -> bool {
        match *self.as_element() {
            TemplateElement::Expression(ref ht) => !ht.is_name_only(),
            _ => false,
        }
    }

    pub fn as_element(&self) -> &TemplateElement {
        self.element.as_ref()
    }

    pub fn name(&self) -> &str {
        match *self.as_element() {
            // FIXME: avoid unwrap here
            Expression(ref ht) => ht.name.as_name().unwrap(),
            _ => unreachable!(),
        }
    }

    pub fn params(&self) -> Option<&Vec<Parameter>> {
        match *self.as_element() {
            Expression(ref ht) => Some(&ht.params),
            _ => None,
        }
    }

    pub fn hash(&self) -> Option<&HashMap<String, Parameter>> {
        match *self.as_element() {
            Expression(ref ht) => Some(&ht.hash),
            _ => None,
        }
    }
}

#[derive(PartialEq, Clone, Debug)]
pub enum BlockParam {
    Single(Parameter),
    Pair((Parameter, Parameter)),
}

#[derive(PartialEq, Clone, Debug)]
pub struct ExpressionSpec {
    pub name: Parameter,
    pub params: Vec<Parameter>,
    pub hash: HashMap<String, Parameter>,
    pub block_param: Option<BlockParam>,
    pub omit_pre_ws: bool,
    pub omit_pro_ws: bool,
}

#[derive(PartialEq, Clone, Debug)]
pub enum Parameter {
    // for helper name only
    Name(String),
    // for expression, helper param and hash
    Path(Path),
    Literal(Json),
    Subexpression(Subexpression),
}

#[derive(PartialEq, Clone, Debug)]
pub struct HelperTemplate {
    pub name: Parameter,
    pub params: Vec<Parameter>,
    pub hash: HashMap<String, Parameter>,
    pub block_param: Option<BlockParam>,
    pub template: Option<Template>,
    pub inverse: Option<Template>,
    pub block: bool,
}

impl HelperTemplate {
    // test only
    pub(crate) fn with_path(path: Path) -> HelperTemplate {
        HelperTemplate {
            name: Parameter::Path(path),
            params: Vec::with_capacity(5),
            hash: HashMap::new(),
            block_param: None,
            template: None,
            inverse: None,
            block: false,
        }
    }

    pub(crate) fn is_name_only(&self) -> bool {
        !self.block && self.params.is_empty() && self.hash.is_empty()
    }
}

#[derive(PartialEq, Clone, Debug)]
pub struct DecoratorTemplate {
    pub name: Parameter,
    pub params: Vec<Parameter>,
    pub hash: HashMap<String, Parameter>,
    pub template: Option<Template>,
}

impl Parameter {
    pub fn as_name(&self) -> Option<&str> {
        match self {
            Parameter::Name(ref n) => Some(n),
            Parameter::Path(ref p) => Some(p.raw()),
            _ => None,
        }
    }

    pub fn parse(s: &str) -> Result<Parameter, TemplateError> {
        let parser = HandlebarsParser::parse(Rule::parameter, s)
            .map_err(|_| TemplateError::of(TemplateErrorReason::InvalidParam(s.to_owned())))?;

        let mut it = parser.flatten().peekable();
        Template::parse_param(s, &mut it, s.len() - 1)
    }

    fn debug_name(&self) -> String {
        if let Some(name) = self.as_name() {
            name.to_owned()
        } else {
            format!("{:?}", self)
        }
    }
}

impl Template {
    pub fn new() -> Template {
        Template::default()
    }

    fn push_element(&mut self, e: TemplateElement, line: usize, col: usize) {
        self.elements.push(e);
        self.mapping.push(TemplateMapping(line, col));
    }

    fn parse_subexpression<'a, I>(
        source: &'a str,
        it: &mut Peekable<I>,
        limit: usize,
    ) -> Result<Parameter, TemplateError>
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let espec = Template::parse_expression(source, it.by_ref(), limit)?;
        Ok(Parameter::Subexpression(Subexpression::new(
            espec.name,
            espec.params,
            espec.hash,
        )))
    }

    fn parse_name<'a, I>(
        source: &'a str,
        it: &mut Peekable<I>,
        _: usize,
    ) -> Result<Parameter, TemplateError>
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let name_node = it.next().unwrap();
        let rule = name_node.as_rule();
        let name_span = name_node.as_span();
        match rule {
            Rule::identifier | Rule::partial_identifier | Rule::invert_tag_item => {
                Ok(Parameter::Name(name_span.as_str().to_owned()))
            }
            Rule::reference => {
                let paths = parse_json_path_from_iter(it, name_span.end());
                Ok(Parameter::Path(Path::new(name_span.as_str(), paths)))
            }
            Rule::subexpression => {
                Template::parse_subexpression(source, it.by_ref(), name_span.end())
            }
            _ => unreachable!(),
        }
    }

    fn parse_param<'a, I>(
        source: &'a str,
        it: &mut Peekable<I>,
        _: usize,
    ) -> Result<Parameter, TemplateError>
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let mut param = it.next().unwrap();
        if param.as_rule() == Rule::param {
            param = it.next().unwrap();
        }
        let param_rule = param.as_rule();
        let param_span = param.as_span();
        let result = match param_rule {
            Rule::reference => {
                let path_segs = parse_json_path_from_iter(it, param_span.end());
                Parameter::Path(Path::new(param_span.as_str(), path_segs))
            }
            Rule::literal => {
                let s = param_span.as_str();
                if let Ok(json) = Json::from_str(s) {
                    Parameter::Literal(json)
                } else {
                    Parameter::Name(s.to_owned())
                }
            }
            Rule::subexpression => {
                Template::parse_subexpression(source, it.by_ref(), param_span.end())?
            }
            _ => unreachable!(),
        };

        while let Some(n) = it.peek() {
            let n_span = n.as_span();
            if n_span.end() > param_span.end() {
                break;
            }
            it.next();
        }

        Ok(result)
    }

    fn parse_hash<'a, I>(
        source: &'a str,
        it: &mut Peekable<I>,
        limit: usize,
    ) -> Result<(String, Parameter), TemplateError>
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let name = it.next().unwrap();
        let name_node = name.as_span();
        // identifier
        let key = name_node.as_str().to_owned();

        let value = Template::parse_param(source, it.by_ref(), limit)?;
        Ok((key, value))
    }

    fn parse_block_param<'a, I>(_: &'a str, it: &mut Peekable<I>, limit: usize) -> BlockParam
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let p1_name = it.next().unwrap();
        let p1_name_span = p1_name.as_span();
        // identifier
        let p1 = p1_name_span.as_str().to_owned();

        let p2 = it.peek().and_then(|p2_name| {
            let p2_name_span = p2_name.as_span();
            if p2_name_span.end() <= limit {
                Some(p2_name_span.as_str().to_owned())
            } else {
                None
            }
        });

        if let Some(p2) = p2 {
            it.next();
            BlockParam::Pair((Parameter::Name(p1), Parameter::Name(p2)))
        } else {
            BlockParam::Single(Parameter::Name(p1))
        }
    }

    fn parse_expression<'a, I>(
        source: &'a str,
        it: &mut Peekable<I>,
        limit: usize,
    ) -> Result<ExpressionSpec, TemplateError>
    where
        I: Iterator<Item = Pair<'a, Rule>>,
    {
        let mut params: Vec<Parameter> = Vec::new();
        let mut hashes: HashMap<String, Parameter> = HashMap::new();
        let mut omit_pre_ws = false;
        let mut omit_pro_ws = false;
        let mut block_param = None;

        if it.peek().unwrap().as_rule() == Rule::pre_whitespace_omitter {
            omit_pre_ws = true;
            it.next();
        }

        let name = Template::parse_name(source, it.by_ref(), limit)?;

        loop {
            let rule;
            let end;
            if let Some(pair) = it.peek() {
                let pair_span = pair.as_span();
                if pair_span.end() < limit {
                    rule = pair.as_rule();
                    end = pair_span.end();
                } else {
                    break;
                }
            } else {
                break;
            }

            it.next();

            match rule {
                Rule::param => {
                    params.push(Template::parse_param(source, it.by_ref(), end)?);
                }
                Rule::hash => {
                    let (key, value) = Template::parse_hash(source, it.by_ref(), end)?;
                    hashes.insert(key, value);
                }
                Rule::block_param => {
                    block_param = Some(Template::parse_block_param(source, it.by_ref(), end));
                }
                Rule::pro_whitespace_omitter => {
                    omit_pro_ws = true;
                }
                _ => {}
            }
        }
        Ok(ExpressionSpec {
            name,
            params,
            hash: hashes,
            block_param,
            omit_pre_ws,
            omit_pro_ws,
        })
    }

    fn remove_previous_whitespace(template_stack: &mut VecDeque<Template>) {
        let t = template_stack.front_mut().unwrap();
        if let Some(RawString(ref mut text)) = t.elements.last_mut() {
            *text = text.trim_end().to_owned();
        }
    }

    fn process_standalone_statement(
        template_stack: &mut VecDeque<Template>,
        source: &str,
        current_span: &Span<'_>,
        prevent_indent: bool,
    ) -> bool {
        let with_trailing_newline = grammar::starts_with_empty_line(&source[current_span.end()..]);

        if with_trailing_newline {
            let with_leading_newline =
                grammar::ends_with_empty_line(&source[..current_span.start()]);

            // prevent_indent: a special toggle for partial expression
            // (>) that leading whitespaces are kept, default to false
            if prevent_indent && with_leading_newline {
                let t = template_stack.front_mut().unwrap();
                // check the last element before current
                if let Some(RawString(ref mut text)) = t.elements.last_mut() {
                    // trim leading space for standalone statement
                    *text = text
                        .trim_end_matches(grammar::whitespace_matcher)
                        .to_owned();
                }
            }

            // return true when the item is the first element in root template
            current_span.start() == 0 || with_leading_newline
        } else {
            false
        }
    }

    fn raw_string<'a>(
        source: &'a str,
        pair: Option<Pair<'a, Rule>>,
        trim_start: bool,
        trim_start_line: bool,
    ) -> TemplateElement {
        let mut s = String::from(source);

        if let Some(pair) = pair {
            // the source may contains leading space because of pest's limitation
            // we calculate none space start here in order to correct the offset
            let pair_span = pair.as_span();

            let current_start = pair_span.start();
            let span_length = pair_span.end() - current_start;
            let leading_space_offset = s.len() - span_length;

            // we would like to iterate pair reversely in order to remove certain
            // index from our string buffer so here we convert the inner pairs to
            // a vector.
            for sub_pair in pair.into_inner().rev() {
                // remove escaped backslash
                if sub_pair.as_rule() == Rule::escape {
                    let escape_span = sub_pair.as_span();

                    let backslash_pos = escape_span.start();
                    let backslash_rel_pos = leading_space_offset + backslash_pos - current_start;
                    s.remove(backslash_rel_pos);
                }
            }
        }

        if trim_start {
            RawString(s.trim_start().to_owned())
        } else if trim_start_line {
            let s = s.trim_start_matches(grammar::whitespace_matcher);
            RawString(grammar::strip_first_newline(s).to_owned())
        } else {
            RawString(s)
        }
    }

    pub(crate) fn compile2<'a>(
        source: &'a str,
        options: TemplateOptions,
    ) -> Result<Template, TemplateError> {
        let mut helper_stack: VecDeque<HelperTemplate> = VecDeque::new();
        let mut decorator_stack: VecDeque<DecoratorTemplate> = VecDeque::new();
        let mut template_stack: VecDeque<Template> = VecDeque::new();

        let mut omit_pro_ws = false;
        // flag for newline removal of standalone statements
        // this option is marked as true when standalone statement is detected
        // then the leading whitespaces and newline of next rawstring will be trimed
        let mut trim_line_required = false;

        let parser_queue = HandlebarsParser::parse(Rule::handlebars, source).map_err(|e| {
            let (line_no, col_no) = match e.line_col {
                LineColLocation::Pos(line_col) => line_col,
                LineColLocation::Span(line_col, _) => line_col,
            };
            TemplateError::of(TemplateErrorReason::InvalidSyntax)
                .at(source, line_no, col_no)
                .in_template(options.name())
        })?;

        // dbg!(parser_queue.clone().flatten());

        // remove escape from our pair queue
        let mut it = parser_queue
            .flatten()
            .filter(|p| {
                // remove rules that should be silent but not for now due to pest limitation
                !matches!(p.as_rule(), Rule::escape)
            })
            .peekable();
        let mut end_pos: Option<Position<'_>> = None;
        loop {
            if let Some(pair) = it.next() {
                let prev_end = end_pos.as_ref().map(|p| p.pos()).unwrap_or(0);
                let rule = pair.as_rule();
                let span = pair.as_span();

                let is_trailing_string = rule != Rule::template
                    && span.start() != prev_end
                    && !omit_pro_ws
                    && rule != Rule::raw_text
                    && rule != Rule::raw_block_text;

                if is_trailing_string {
                    // trailing string check
                    let (line_no, col_no) = span.start_pos().line_col();
                    if rule == Rule::raw_block_end {
                        let mut t = Template::new();
                        t.push_element(
                            Template::raw_string(
                                &source[prev_end..span.start()],
                                None,
                                false,
                                trim_line_required,
                            ),
                            line_no,
                            col_no,
                        );
                        template_stack.push_front(t);
                    } else {
                        let t = template_stack.front_mut().unwrap();
                        t.push_element(
                            Template::raw_string(
                                &source[prev_end..span.start()],
                                None,
                                false,
                                trim_line_required,
                            ),
                            line_no,
                            col_no,
                        );
                    }

                    // reset standalone statement marker
                    trim_line_required = false;
                }

                let (line_no, col_no) = span.start_pos().line_col();
                match rule {
                    Rule::template => {
                        template_stack.push_front(Template::new());
                    }
                    Rule::raw_text => {
                        // leading space fix
                        let start = if span.start() != prev_end {
                            prev_end
                        } else {
                            span.start()
                        };

                        let t = template_stack.front_mut().unwrap();
                        t.push_element(
                            Template::raw_string(
                                &source[start..span.end()],
                                Some(pair.clone()),
                                omit_pro_ws,
                                trim_line_required,
                            ),
                            line_no,
                            col_no,
                        );

                        // reset standalone statement marker
                        trim_line_required = false;
                    }
                    Rule::helper_block_start
                    | Rule::raw_block_start
                    | Rule::decorator_block_start
                    | Rule::partial_block_start => {
                        let exp = Template::parse_expression(source, it.by_ref(), span.end())?;

                        match rule {
                            Rule::helper_block_start | Rule::raw_block_start => {
                                let helper_template = HelperTemplate {
                                    name: exp.name,
                                    params: exp.params,
                                    hash: exp.hash,
                                    block_param: exp.block_param,
                                    block: true,
                                    template: None,
                                    inverse: None,
                                };
                                helper_stack.push_front(helper_template);
                            }
                            Rule::decorator_block_start | Rule::partial_block_start => {
                                let decorator = DecoratorTemplate {
                                    name: exp.name,
                                    params: exp.params,
                                    hash: exp.hash,
                                    template: None,
                                };
                                decorator_stack.push_front(decorator);
                            }
                            _ => unreachable!(),
                        }

                        if exp.omit_pre_ws {
                            Template::remove_previous_whitespace(&mut template_stack);
                        }
                        omit_pro_ws = exp.omit_pro_ws;

                        // standalone statement check, it also removes leading whitespaces of
                        // previous rawstring when standalone statement detected
                        trim_line_required = Template::process_standalone_statement(
                            &mut template_stack,
                            source,
                            &span,
                            true,
                        );

                        let t = template_stack.front_mut().unwrap();
                        t.mapping.push(TemplateMapping(line_no, col_no));
                    }
                    Rule::invert_tag => {
                        // hack: invert_tag structure is similar to ExpressionSpec, so I
                        // use it here to represent the data
                        let exp = Template::parse_expression(source, it.by_ref(), span.end())?;

                        if exp.omit_pre_ws {
                            Template::remove_previous_whitespace(&mut template_stack);
                        }
                        omit_pro_ws = exp.omit_pro_ws;

                        // standalone statement check, it also removes leading whitespaces of
                        // previous rawstring when standalone statement detected
                        trim_line_required = Template::process_standalone_statement(
                            &mut template_stack,
                            source,
                            &span,
                            true,
                        );

                        let t = template_stack.pop_front().unwrap();
                        let h = helper_stack.front_mut().unwrap();
                        h.template = Some(t);
                    }
                    Rule::raw_block_text => {
                        let mut t = Template::new();
                        t.push_element(
                            Template::raw_string(
                                span.as_str(),
                                Some(pair.clone()),
                                omit_pro_ws,
                                trim_line_required,
                            ),
                            line_no,
                            col_no,
                        );
                        template_stack.push_front(t);
                    }
                    Rule::expression
                    | Rule::html_expression
                    | Rule::decorator_expression
                    | Rule::partial_expression
                    | Rule::helper_block_end
                    | Rule::raw_block_end
                    | Rule::decorator_block_end
                    | Rule::partial_block_end => {
                        let exp = Template::parse_expression(source, it.by_ref(), span.end())?;

                        if exp.omit_pre_ws {
                            Template::remove_previous_whitespace(&mut template_stack);
                        }
                        omit_pro_ws = exp.omit_pro_ws;

                        match rule {
                            Rule::expression | Rule::html_expression => {
                                let helper_template = HelperTemplate {
                                    name: exp.name,
                                    params: exp.params,
                                    hash: exp.hash,
                                    block_param: exp.block_param,
                                    block: false,
                                    template: None,
                                    inverse: None,
                                };
                                let el = if rule == Rule::expression {
                                    Expression(Box::new(helper_template))
                                } else {
                                    HtmlExpression(Box::new(helper_template))
                                };
                                let t = template_stack.front_mut().unwrap();
                                t.push_element(el, line_no, col_no);
                            }
                            Rule::decorator_expression | Rule::partial_expression => {
                                // do not auto trim ident spaces for
                                // partial_expression(>)
                                let prevent_indent =
                                    options.prevent_indent || rule != Rule::partial_expression;
                                trim_line_required = Template::process_standalone_statement(
                                    &mut template_stack,
                                    source,
                                    &span,
                                    prevent_indent,
                                );

                                let decorator = DecoratorTemplate {
                                    name: exp.name,
                                    params: exp.params,
                                    hash: exp.hash,
                                    template: None,
                                };
                                let el = if rule == Rule::decorator_expression {
                                    DecoratorExpression(Box::new(decorator))
                                } else {
                                    PartialExpression(Box::new(decorator))
                                };
                                let t = template_stack.front_mut().unwrap();
                                t.push_element(el, line_no, col_no);
                            }
                            Rule::helper_block_end | Rule::raw_block_end => {
                                // standalone statement check, it also removes leading whitespaces of
                                // previous rawstring when standalone statement detected
                                trim_line_required = Template::process_standalone_statement(
                                    &mut template_stack,
                                    source,
                                    &span,
                                    true,
                                );

                                let mut h = helper_stack.pop_front().unwrap();
                                let close_tag_name = exp.name.as_name();
                                if h.name.as_name() == close_tag_name {
                                    let prev_t = template_stack.pop_front().unwrap();
                                    if h.template.is_some() {
                                        h.inverse = Some(prev_t);
                                    } else {
                                        h.template = Some(prev_t);
                                    }
                                    let t = template_stack.front_mut().unwrap();
                                    t.elements.push(HelperBlock(Box::new(h)));
                                } else {
                                    return Err(TemplateError::of(
                                        TemplateErrorReason::MismatchingClosedHelper(
                                            h.name.debug_name(),
                                            exp.name.debug_name(),
                                        ),
                                    )
                                    .at(source, line_no, col_no)
                                    .in_template(options.name()));
                                }
                            }
                            Rule::decorator_block_end | Rule::partial_block_end => {
                                // standalone statement check, it also removes leading whitespaces of
                                // previous rawstring when standalone statement detected
                                trim_line_required = Template::process_standalone_statement(
                                    &mut template_stack,
                                    source,
                                    &span,
                                    true,
                                );

                                let mut d = decorator_stack.pop_front().unwrap();
                                let close_tag_name = exp.name.as_name();
                                if d.name.as_name() == close_tag_name {
                                    let prev_t = template_stack.pop_front().unwrap();
                                    d.template = Some(prev_t);
                                    let t = template_stack.front_mut().unwrap();
                                    if rule == Rule::decorator_block_end {
                                        t.elements.push(DecoratorBlock(Box::new(d)));
                                    } else {
                                        t.elements.push(PartialBlock(Box::new(d)));
                                    }
                                } else {
                                    return Err(TemplateError::of(
                                        TemplateErrorReason::MismatchingClosedDecorator(
                                            d.name.debug_name(),
                                            exp.name.debug_name(),
                                        ),
                                    )
                                    .at(source, line_no, col_no)
                                    .in_template(options.name()));
                                }
                            }
                            _ => unreachable!(),
                        }
                    }
                    Rule::hbs_comment_compact => {
                        trim_line_required = Template::process_standalone_statement(
                            &mut template_stack,
                            source,
                            &span,
                            true,
                        );

                        let text = span
                            .as_str()
                            .trim_start_matches("{{!")
                            .trim_end_matches("}}");
                        let t = template_stack.front_mut().unwrap();
                        t.push_element(Comment(text.to_owned()), line_no, col_no);
                    }
                    Rule::hbs_comment => {
                        trim_line_required = Template::process_standalone_statement(
                            &mut template_stack,
                            source,
                            &span,
                            true,
                        );

                        let text = span
                            .as_str()
                            .trim_start_matches("{{!--")
                            .trim_end_matches("--}}");
                        let t = template_stack.front_mut().unwrap();
                        t.push_element(Comment(text.to_owned()), line_no, col_no);
                    }
                    _ => {}
                }

                if rule != Rule::template {
                    end_pos = Some(span.end_pos());
                }
            } else {
                let prev_end = end_pos.as_ref().map(|e| e.pos()).unwrap_or(0);
                if prev_end < source.len() {
                    let text = &source[prev_end..source.len()];
                    // is some called in if check
                    let (line_no, col_no) = end_pos.unwrap().line_col();
                    let t = template_stack.front_mut().unwrap();
                    t.push_element(RawString(text.to_owned()), line_no, col_no);
                }
                let mut root_template = template_stack.pop_front().unwrap();
                root_template.name = options.name;
                return Ok(root_template);
            }
        }
    }

    // These two compile functions are kept for compatibility with 4.x
    // Template APIs in case that some developers are using them
    // without registry.

    pub fn compile(source: &str) -> Result<Template, TemplateError> {
        Self::compile2(source, TemplateOptions::default())
    }

    pub fn compile_with_name<S: AsRef<str>>(
        source: S,
        name: String,
    ) -> Result<Template, TemplateError> {
        Self::compile2(
            source.as_ref(),
            TemplateOptions {
                name: Some(name),
                ..Default::default()
            },
        )
    }
}

#[derive(PartialEq, Clone, Debug)]
pub enum TemplateElement {
    RawString(String),
    HtmlExpression(Box<HelperTemplate>),
    Expression(Box<HelperTemplate>),
    HelperBlock(Box<HelperTemplate>),
    DecoratorExpression(Box<DecoratorTemplate>),
    DecoratorBlock(Box<DecoratorTemplate>),
    PartialExpression(Box<DecoratorTemplate>),
    PartialBlock(Box<DecoratorTemplate>),
    Comment(String),
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::error::TemplateErrorReason;

    #[test]
    fn test_parse_escaped_tag_raw_string() {
        let source = r"foo \{{bar}}";
        let t = Template::compile(source).ok().unwrap();
        assert_eq!(t.elements.len(), 1);
        assert_eq!(
            *t.elements.get(0).unwrap(),
            RawString("foo {{bar}}".to_string())
        );
    }

    #[test]
    fn test_pure_backslash_raw_string() {
        let source = r"\\\\";
        let t = Template::compile(source).ok().unwrap();
        assert_eq!(t.elements.len(), 1);
        assert_eq!(*t.elements.get(0).unwrap(), RawString(source.to_string()));
    }

    #[test]
    fn test_parse_escaped_block_raw_string() {
        let source = r"\{{{{foo}}}} bar";
        let t = Template::compile(source).ok().unwrap();
        assert_eq!(t.elements.len(), 1);
        assert_eq!(
            *t.elements.get(0).unwrap(),
            RawString("{{{{foo}}}} bar".to_string())
        );
    }

    #[test]
    fn test_parse_template() {
        let source = "<h1>{{title}} 你好</h1> {{{content}}}
{{#if date}}<p>good</p>{{else}}<p>bad</p>{{/if}}<img>{{foo bar}}中文你好
{{#unless true}}kitkat{{^}}lollipop{{/unless}}";
        let t = Template::compile(source).ok().unwrap();

        assert_eq!(t.elements.len(), 10);

        assert_eq!(*t.elements.get(0).unwrap(), RawString("<h1>".to_string()));
        assert_eq!(
            *t.elements.get(1).unwrap(),
            Expression(Box::new(HelperTemplate::with_path(Path::with_named_paths(
                &["title"]
            ))))
        );

        assert_eq!(
            *t.elements.get(3).unwrap(),
            HtmlExpression(Box::new(HelperTemplate::with_path(Path::with_named_paths(
                &["content"],
            ))))
        );

        match *t.elements.get(5).unwrap() {
            HelperBlock(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "if".to_string());
                assert_eq!(h.params.len(), 1);
                assert_eq!(h.template.as_ref().unwrap().elements.len(), 1);
            }
            _ => {
                panic!("Helper expected here.");
            }
        };

        match *t.elements.get(7).unwrap() {
            Expression(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "foo".to_string());
                assert_eq!(h.params.len(), 1);
                assert_eq!(
                    *(h.params.get(0).unwrap()),
                    Parameter::Path(Path::with_named_paths(&["bar"]))
                )
            }
            _ => {
                panic!("Helper expression here");
            }
        };

        match *t.elements.get(9).unwrap() {
            HelperBlock(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "unless".to_string());
                assert_eq!(h.params.len(), 1);
                assert_eq!(h.inverse.as_ref().unwrap().elements.len(), 1);
            }
            _ => {
                panic!("Helper expression here");
            }
        };
    }

    #[test]
    fn test_parse_block_partial_path_identifier() {
        let source = "{{#> foo/bar}}{{/foo/bar}}";
        assert!(Template::compile(source).is_ok());
    }

    #[test]
    fn test_parse_error() {
        let source = "{{#ifequals name compare=\"hello\"}}\nhello\n\t{{else}}\ngood";

        let terr = Template::compile(source).unwrap_err();

        assert!(matches!(terr.reason, TemplateErrorReason::InvalidSyntax));
        assert_eq!(terr.line_no.unwrap(), 4);
        assert_eq!(terr.column_no.unwrap(), 5);
    }

    #[test]
    fn test_subexpression() {
        let source =
            "{{foo (bar)}}{{foo (bar baz)}} hello {{#if (baz bar) then=(bar)}}world{{/if}}";
        let t = Template::compile(source).ok().unwrap();

        assert_eq!(t.elements.len(), 4);
        match *t.elements.get(0).unwrap() {
            Expression(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "foo".to_owned());
                assert_eq!(h.params.len(), 1);
                if let &Parameter::Subexpression(ref t) = h.params.get(0).unwrap() {
                    assert_eq!(t.name(), "bar".to_owned());
                } else {
                    panic!("Subexpression expected");
                }
            }
            _ => {
                panic!("Helper expression expected");
            }
        };

        match *t.elements.get(1).unwrap() {
            Expression(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "foo".to_string());
                assert_eq!(h.params.len(), 1);
                if let &Parameter::Subexpression(ref t) = h.params.get(0).unwrap() {
                    assert_eq!(t.name(), "bar".to_owned());
                    if let Some(Parameter::Path(p)) = t.params().unwrap().get(0) {
                        assert_eq!(p, &Path::with_named_paths(&["baz"]));
                    } else {
                        panic!("non-empty param expected ");
                    }
                } else {
                    panic!("Subexpression expected");
                }
            }
            _ => {
                panic!("Helper expression expected");
            }
        };

        match *t.elements.get(3).unwrap() {
            HelperBlock(ref h) => {
                assert_eq!(h.name.as_name().unwrap(), "if".to_string());
                assert_eq!(h.params.len(), 1);
                assert_eq!(h.hash.len(), 1);

                if let &Parameter::Subexpression(ref t) = h.params.get(0).unwrap() {
                    assert_eq!(t.name(), "baz".to_owned());
                    if let Some(Parameter::Path(p)) = t.params().unwrap().get(0) {
                        assert_eq!(p, &Path::with_named_paths(&["bar"]));
                    } else {
                        panic!("non-empty param expected ");
                    }
                } else {
                    panic!("Subexpression expected (baz bar)");
                }

                if let &Parameter::Subexpression(ref t) = h.hash.get("then").unwrap() {
                    assert_eq!(t.name(), "bar".to_owned());
                } else {
                    panic!("Subexpression expected (bar)");
                }
            }
            _ => {
                panic!("HelperBlock expected");
            }
        }
    }

    #[test]
    fn test_white_space_omitter() {
        let source = "hello~     {{~world~}} \n  !{{~#if true}}else{{/if~}}";
        let t = Template::compile(source).ok().unwrap();

        assert_eq!(t.elements.len(), 4);

        assert_eq!(t.elements[0], RawString("hello~".to_string()));
        assert_eq!(
            t.elements[1],
            Expression(Box::new(HelperTemplate::with_path(Path::with_named_paths(
                &["world"]
            ))))
        );
        assert_eq!(t.elements[2], RawString("!".to_string()));

        let t2 = Template::compile("{{#if true}}1  {{~ else ~}} 2 {{~/if}}")
            .ok()
            .unwrap();
        assert_eq!(t2.elements.len(), 1);
        match t2.elements[0] {
            HelperBlock(ref h) => {
                assert_eq!(
                    h.template.as_ref().unwrap().elements[0],
                    RawString("1".to_string())
                );
                assert_eq!(
                    h.inverse.as_ref().unwrap().elements[0],
                    RawString("2".to_string())
                );
            }
            _ => unreachable!(),
        }
    }

    #[test]
    fn test_unclosed_expression() {
        let sources = ["{{invalid", "{{{invalid", "{{invalid}", "{{!hello"];
        for s in sources.iter() {
            let result = Template::compile(s.to_owned());
            if let Err(e) = result {
                match e.reason {
                    TemplateErrorReason::InvalidSyntax => {}
                    _ => {
                        panic!("Unexpected error type {}", e);
                    }
                }
            } else {
                panic!("Undetected error");
            }
        }
    }

    #[test]
    fn test_raw_helper() {
        let source = "hello{{{{raw}}}}good{{night}}{{{{/raw}}}}world";
        match Template::compile(source) {
            Ok(t) => {
                assert_eq!(t.elements.len(), 3);
                assert_eq!(t.elements[0], RawString("hello".to_owned()));
                assert_eq!(t.elements[2], RawString("world".to_owned()));
                match t.elements[1] {
                    HelperBlock(ref h) => {
                        assert_eq!(h.name.as_name().unwrap(), "raw".to_owned());
                        if let Some(ref ht) = h.template {
                            assert_eq!(ht.elements.len(), 1);
                            assert_eq!(
                                *ht.elements.get(0).unwrap(),
                                RawString("good{{night}}".to_owned())
                            );
                        } else {
                            panic!("helper template not found");
                        }
                    }
                    _ => {
                        panic!("Unexpected element type");
                    }
                }
            }
            Err(e) => {
                panic!("{}", e);
            }
        }
    }

    #[test]
    fn test_literal_parameter_parser() {
        match Template::compile("{{hello 1 name=\"value\" valid=false ref=someref}}") {
            Ok(t) => {
                if let Expression(ref ht) = t.elements[0] {
                    assert_eq!(ht.params[0], Parameter::Literal(json!(1)));
                    assert_eq!(
                        ht.hash["name"],
                        Parameter::Literal(Json::String("value".to_owned()))
                    );
                    assert_eq!(ht.hash["valid"], Parameter::Literal(Json::Bool(false)));
                    assert_eq!(
                        ht.hash["ref"],
                        Parameter::Path(Path::with_named_paths(&["someref"]))
                    );
                }
            }
            Err(e) => panic!("{}", e),
        }
    }

    #[test]
    fn test_template_mapping() {
        match Template::compile("hello\n  {{~world}}\n{{#if nice}}\n\thello\n{{/if}}") {
            Ok(t) => {
                assert_eq!(t.mapping.len(), t.elements.len());
                assert_eq!(t.mapping[0], TemplateMapping(1, 1));
                assert_eq!(t.mapping[1], TemplateMapping(2, 3));
                assert_eq!(t.mapping[3], TemplateMapping(3, 1));
            }
            Err(e) => panic!("{}", e),
        }
    }

    #[test]
    fn test_whitespace_elements() {
        let c = Template::compile(
            "  {{elem}}\n\t{{#if true}} \
         {{/if}}\n{{{{raw}}}} {{{{/raw}}}}\n{{{{raw}}}}{{{{/raw}}}}\n",
        );
        let r = c.unwrap();
        // the \n after last raw block is dropped by pest
        assert_eq!(r.elements.len(), 9);
    }

    #[test]
    fn test_block_param() {
        match Template::compile("{{#each people as |person|}}{{person}}{{/each}}") {
            Ok(t) => {
                if let HelperBlock(ref ht) = t.elements[0] {
                    if let Some(BlockParam::Single(Parameter::Name(ref n))) = ht.block_param {
                        assert_eq!(n, "person");
                    } else {
                        panic!("block param expected.")
                    }
                } else {
                    panic!("Helper block expected");
                }
            }
            Err(e) => panic!("{}", e),
        }

        match Template::compile("{{#each people as |val key|}}{{person}}{{/each}}") {
            Ok(t) => {
                if let HelperBlock(ref ht) = t.elements[0] {
                    if let Some(BlockParam::Pair((
                        Parameter::Name(ref n1),
                        Parameter::Name(ref n2),
                    ))) = ht.block_param
                    {
                        assert_eq!(n1, "val");
                        assert_eq!(n2, "key");
                    } else {
                        panic!("helper block param expected.");
                    }
                } else {
                    panic!("Helper block expected");
                }
            }
            Err(e) => panic!("{}", e),
        }
    }

    #[test]
    fn test_decorator() {
        match Template::compile("hello {{* ssh}} world") {
            Err(e) => panic!("{}", e),
            Ok(t) => {
                if let DecoratorExpression(ref de) = t.elements[1] {
                    assert_eq!(de.name.as_name(), Some("ssh"));
                    assert_eq!(de.template, None);
                }
            }
        }

        match Template::compile("hello {{> ssh}} world") {
            Err(e) => panic!("{}", e),
            Ok(t) => {
                if let PartialExpression(ref de) = t.elements[1] {
                    assert_eq!(de.name.as_name(), Some("ssh"));
                    assert_eq!(de.template, None);
                }
            }
        }

        match Template::compile("{{#*inline \"hello\"}}expand to hello{{/inline}}{{> hello}}") {
            Err(e) => panic!("{}", e),
            Ok(t) => {
                if let DecoratorBlock(ref db) = t.elements[0] {
                    assert_eq!(db.name, Parameter::Name("inline".to_owned()));
                    assert_eq!(
                        db.params[0],
                        Parameter::Literal(Json::String("hello".to_owned()))
                    );
                    assert_eq!(
                        db.template.as_ref().unwrap().elements[0],
                        TemplateElement::RawString("expand to hello".to_owned())
                    );
                }
            }
        }

        match Template::compile("{{#> layout \"hello\"}}expand to hello{{/layout}}{{> hello}}") {
            Err(e) => panic!("{}", e),
            Ok(t) => {
                if let PartialBlock(ref db) = t.elements[0] {
                    assert_eq!(db.name, Parameter::Name("layout".to_owned()));
                    assert_eq!(
                        db.params[0],
                        Parameter::Literal(Json::String("hello".to_owned()))
                    );
                    assert_eq!(
                        db.template.as_ref().unwrap().elements[0],
                        TemplateElement::RawString("expand to hello".to_owned())
                    );
                }
            }
        }
    }

    #[test]
    fn test_panic_with_tag_name() {
        let s = "{{#>(X)}}{{/X}}";
        let result = Template::compile(s);
        assert!(result.is_err());
        assert_eq!("decorator \"Subexpression(Subexpression { element: Expression(HelperTemplate { name: Path(Relative(([Named(\\\"X\\\")], \\\"X\\\"))), params: [], hash: {}, block_param: None, template: None, inverse: None, block: false }) })\" was opened, but \"X\" is closing", format!("{}", result.unwrap_err().reason));
    }
}
