#![allow(deprecated)]

/// The compiler module houses the code which parses and compiles templates. TinyTemplate implements
/// a simple bytecode interpreter (see the [instruction] module for more details) to render templates.
/// The [`TemplateCompiler`](struct.TemplateCompiler.html) struct is responsible for parsing the
/// template strings and generating the appropriate bytecode instructions.
use error::Error::*;
use error::{get_offset, Error, Result};
use instruction::{Instruction, Path, PathStep};

/// The end point of a branch or goto instruction is not known.
const UNKNOWN: usize = ::std::usize::MAX;

/// The compiler keeps a stack of the open blocks so that it can ensure that blocks are closed in
/// the right order. The Block type is a simple enumeration of the kinds of blocks that could be
/// open. It may contain the instruction index corresponding to the start of the block.
enum Block {
    Branch(usize),
    For(usize),
    With,
}

/// List of the known @-keywords so that we can error if the user spells them wrong.
static KNOWN_KEYWORDS: [&str; 4] = ["@index", "@first", "@last", "@root"];

/// The TemplateCompiler struct is responsible for parsing a template string and generating bytecode
/// instructions based on it. The parser is a simple hand-written pattern-matching parser with no
/// recursion, which makes it relatively easy to read.
pub(crate) struct TemplateCompiler<'template> {
    original_text: &'template str,
    remaining_text: &'template str,
    instructions: Vec<Instruction<'template>>,
    block_stack: Vec<(&'template str, Block)>,

    /// When we see a `{foo -}` or similar, we need to remember to left-trim the next text block we
    /// encounter.
    trim_next: bool,
}
impl<'template> TemplateCompiler<'template> {
    /// Create a new template compiler to parse and compile the given template.
    pub fn new(text: &'template str) -> TemplateCompiler<'template> {
        TemplateCompiler {
            original_text: text,
            remaining_text: text,
            instructions: vec![],
            block_stack: vec![],
            trim_next: false,
        }
    }

    /// Consume the template compiler to parse the template and return the generated bytecode.
    pub fn compile(mut self) -> Result<Vec<Instruction<'template>>> {
        while !self.remaining_text.is_empty() {
            // Comment, denoted by {# comment text #}
            if self.remaining_text.starts_with("{#") {
                self.trim_next = false;

                let tag = self.consume_tag("#}")?;
                let comment = tag[2..(tag.len() - 2)].trim();
                if comment.starts_with('-') {
                    self.trim_last_whitespace();
                }
                if comment.ends_with('-') {
                    self.trim_next_whitespace();
                }
            // Block tag. Block tags are wrapped in {{ }} and always have one word at the start
            // to identify which kind of tag it is. Depending on the tag type there may be more.
            } else if self.remaining_text.starts_with("{{") {
                self.trim_next = false;

                let (discriminant, rest) = self.consume_block()?;
                match discriminant {
                    "if" => {
                        let (path, negated) = if rest.starts_with("not") {
                            (self.parse_path(&rest[4..])?, true)
                        } else {
                            (self.parse_path(rest)?, false)
                        };
                        self.block_stack
                            .push((discriminant, Block::Branch(self.instructions.len())));
                        self.instructions
                            .push(Instruction::Branch(path, !negated, UNKNOWN));
                    }
                    "else" => {
                        self.expect_empty(rest)?;
                        let num_instructions = self.instructions.len() + 1;
                        self.close_branch(num_instructions, discriminant)?;
                        self.block_stack
                            .push((discriminant, Block::Branch(self.instructions.len())));
                        self.instructions.push(Instruction::Goto(UNKNOWN))
                    }
                    "endif" => {
                        self.expect_empty(rest)?;
                        let num_instructions = self.instructions.len();
                        self.close_branch(num_instructions, discriminant)?;
                    }
                    "with" => {
                        let (path, name) = self.parse_with(rest)?;
                        let instruction = Instruction::PushNamedContext(path, name);
                        self.instructions.push(instruction);
                        self.block_stack.push((discriminant, Block::With));
                    }
                    "endwith" => {
                        self.expect_empty(rest)?;
                        if let Some((_, Block::With)) = self.block_stack.pop() {
                            self.instructions.push(Instruction::PopContext)
                        } else {
                            return Err(self.parse_error(
                                discriminant,
                                "Found a closing endwith that doesn't match with a preceeding with.".to_string()
                            ));
                        }
                    }
                    "for" => {
                        let (path, name) = self.parse_for(rest)?;
                        self.instructions
                            .push(Instruction::PushIterationContext(path, name));
                        self.block_stack
                            .push((discriminant, Block::For(self.instructions.len())));
                        self.instructions.push(Instruction::Iterate(UNKNOWN));
                    }
                    "endfor" => {
                        self.expect_empty(rest)?;
                        let num_instructions = self.instructions.len() + 1;
                        let goto_target = self.close_for(num_instructions, discriminant)?;
                        self.instructions.push(Instruction::Goto(goto_target));
                        self.instructions.push(Instruction::PopContext);
                    }
                    "call" => {
                        let (name, path) = self.parse_call(rest)?;
                        self.instructions.push(Instruction::Call(name, path));
                    }
                    _ => {
                        return Err(self.parse_error(
                            discriminant,
                            format!("Unknown block type '{}'", discriminant),
                        ));
                    }
                }
            // Values, of the form { dotted.path.to.value.in.context }
            // Note that it is not (currently) possible to escape curly braces in the templates to
            // prevent them from being interpreted as values.
            } else if self.remaining_text.starts_with('{') {
                self.trim_next = false;

                let (path, name) = self.consume_value()?;
                let instruction = match name {
                    Some(name) => Instruction::FormattedValue(path, name),
                    None => Instruction::Value(path),
                };
                self.instructions.push(instruction);
            // All other text - just consume characters until we see a {
            } else {
                let mut escaped = false;
                loop {
                    let mut text = self.consume_text(escaped);
                    if self.trim_next {
                        text = text.trim_left();
                        self.trim_next = false;
                    }
                    escaped = text.ends_with('\\');
                    if escaped {
                        text = &text[0..(text.len() - 1)];
                    }
                    self.instructions.push(Instruction::Literal(text));

                    if !escaped {
                        break;
                    }
                }
            }
        }

        if let Some((text, _)) = self.block_stack.pop() {
            return Err(self.parse_error(
                text,
                "Expected block-closing tag, but reached the end of input.".to_string(),
            ));
        }

        Ok(self.instructions)
    }

    /// Splits a string into a list of named segments which can later be used to look up values in the
    /// context.
    fn parse_path(&self, text: &'template str) -> Result<Path<'template>> {
        if !text.starts_with('@') {
            Ok(text
                .split('.')
                .map(|s| match s.parse::<usize>() {
                    Ok(n) => PathStep::Index(s, n),
                    Err(_) => PathStep::Name(s),
                })
                .collect::<Vec<_>>())
        } else if KNOWN_KEYWORDS.iter().any(|k| *k == text) {
            Ok(vec![PathStep::Name(text)])
        } else {
            Err(self.parse_error(text, format!("Invalid keyword name '{}'", text)))
        }
    }

    /// Finds the line number and column where an error occurred. Location is the substring of
    /// self.original_text where the error was found, and msg is the error message.
    fn parse_error(&self, location: &str, msg: String) -> Error {
        let (line, column) = get_offset(self.original_text, location);
        ParseError { msg, line, column }
    }

    /// Tags which should have no text after the discriminant use this to raise an error if
    /// text is found.
    fn expect_empty(&self, text: &str) -> Result<()> {
        if text.is_empty() {
            Ok(())
        } else {
            Err(self.parse_error(text, format!("Unexpected text '{}'", text)))
        }
    }

    /// Close the branch that is on top of the block stack by setting its target instruction
    /// and popping it from the stack. Returns an error if the top of the block stack is not a
    /// branch.
    fn close_branch(&mut self, new_target: usize, discriminant: &str) -> Result<()> {
        let branch_block = self.block_stack.pop();
        if let Some((_, Block::Branch(index))) = branch_block {
            match &mut self.instructions[index] {
                Instruction::Branch(_, _, target) => {
                    *target = new_target;
                    Ok(())
                }
                Instruction::Goto(target) => {
                    *target = new_target;
                    Ok(())
                }
                _ => panic!(),
            }
        } else {
            Err(self.parse_error(
                discriminant,
                "Found a closing endif or else which doesn't match with a preceding if."
                    .to_string(),
            ))
        }
    }

    /// Close the for loop that is on top of the block stack by setting its target instruction and
    /// popping it from the stack. Returns an error if the top of the stack is not a for loop.
    /// Returns the index of the loop's Iterate instruction for further processing.
    fn close_for(&mut self, new_target: usize, discriminant: &str) -> Result<usize> {
        let branch_block = self.block_stack.pop();
        if let Some((_, Block::For(index))) = branch_block {
            match &mut self.instructions[index] {
                Instruction::Iterate(target) => {
                    *target = new_target;
                    Ok(index)
                }
                _ => panic!(),
            }
        } else {
            Err(self.parse_error(
                discriminant,
                "Found a closing endfor which doesn't match with a preceding for.".to_string(),
            ))
        }
    }

    /// Advance the cursor to the next { and return the consumed text. If `escaped` is true, skips
    /// a { at the start of the text.
    fn consume_text(&mut self, escaped: bool) -> &'template str {
        let search_substr = if escaped {
            &self.remaining_text[1..]
        } else {
            self.remaining_text
        };

        let mut position = search_substr
            .find('{')
            .unwrap_or_else(|| search_substr.len());
        if escaped {
            position += 1;
        }

        let (text, remaining) = self.remaining_text.split_at(position);
        self.remaining_text = remaining;
        text
    }

    /// Advance the cursor to the end of the value tag and return the value's path and optional
    /// formatter name.
    fn consume_value(&mut self) -> Result<(Path<'template>, Option<&'template str>)> {
        let tag = self.consume_tag("}")?;
        let mut tag = tag[1..(tag.len() - 1)].trim();
        if tag.starts_with('-') {
            tag = tag[1..].trim();
            self.trim_last_whitespace();
        }
        if tag.ends_with('-') {
            tag = tag[0..tag.len() - 1].trim();
            self.trim_next_whitespace();
        }

        if let Some(index) = tag.find('|') {
            let (path_str, name_str) = tag.split_at(index);
            let name = name_str[1..].trim();
            let path = self.parse_path(path_str.trim())?;
            Ok((path, Some(name)))
        } else {
            Ok((self.parse_path(tag)?, None))
        }
    }

    /// Right-trim whitespace from the last text block we parsed.
    fn trim_last_whitespace(&mut self) {
        if let Some(Instruction::Literal(text)) = self.instructions.last_mut() {
            *text = text.trim_right();
        }
    }

    /// Make a note to left-trim whitespace from the next text block we parse.
    fn trim_next_whitespace(&mut self) {
        self.trim_next = true;
    }

    /// Advance the cursor to the end of the current block tag and return the discriminant substring
    /// and the rest of the text in the tag. Also handles trimming whitespace where needed.
    fn consume_block(&mut self) -> Result<(&'template str, &'template str)> {
        let tag = self.consume_tag("}}")?;
        let mut block = tag[2..(tag.len() - 2)].trim();
        if block.starts_with('-') {
            block = block[1..].trim();
            self.trim_last_whitespace();
        }
        if block.ends_with('-') {
            block = block[0..block.len() - 1].trim();
            self.trim_next_whitespace();
        }
        let discriminant = block.split_whitespace().next().unwrap_or(block);
        let rest = block[discriminant.len()..].trim();
        Ok((discriminant, rest))
    }

    /// Advance the cursor to after the given expected_close string and return the text in between
    /// (including the expected_close characters), or return an error message if we reach the end
    /// of a line of text without finding it.
    fn consume_tag(&mut self, expected_close: &str) -> Result<&'template str> {
        if let Some(line) = self.remaining_text.lines().next() {
            if let Some(pos) = line.find(expected_close) {
                let (tag, remaining) = self.remaining_text.split_at(pos + expected_close.len());
                self.remaining_text = remaining;
                Ok(tag)
            } else {
                Err(self.parse_error(
                    line,
                    format!(
                        "Expected a closing '{}' but found end-of-line instead.",
                        expected_close
                    ),
                ))
            }
        } else {
            Err(self.parse_error(
                self.remaining_text,
                format!(
                    "Expected a closing '{}' but found end-of-text instead.",
                    expected_close
                ),
            ))
        }
    }

    /// Parse a with tag to separate the value path from the (optional) name.
    fn parse_with(&self, with_text: &'template str) -> Result<(Path<'template>, &'template str)> {
        if let Some(index) = with_text.find(" as ") {
            let (path_str, name_str) = with_text.split_at(index);
            let path = self.parse_path(path_str.trim())?;
            let name = name_str[" as ".len()..].trim();
            Ok((path, name))
        } else {
            Err(self.parse_error(
                with_text,
                format!(
                    "Expected 'as <path>' in with block, but found \"{}\" instead",
                    with_text
                ),
            ))
        }
    }

    /// Parse a for tag to separate the value path from the name.
    fn parse_for(&self, for_text: &'template str) -> Result<(Path<'template>, &'template str)> {
        if let Some(index) = for_text.find(" in ") {
            let (name_str, path_str) = for_text.split_at(index);
            let name = name_str.trim();
            let path = self.parse_path(path_str[" in ".len()..].trim())?;
            Ok((path, name))
        } else {
            Err(self.parse_error(
                for_text,
                format!("Unable to parse for block text '{}'", for_text),
            ))
        }
    }

    /// Parse a call tag to separate the template name and context value.
    fn parse_call(&self, call_text: &'template str) -> Result<(&'template str, Path<'template>)> {
        if let Some(index) = call_text.find(" with ") {
            let (name_str, path_str) = call_text.split_at(index);
            let name = name_str.trim();
            let path = self.parse_path(path_str[" with ".len()..].trim())?;
            Ok((name, path))
        } else {
            Err(self.parse_error(
                call_text,
                format!("Unable to parse call block text '{}'", call_text),
            ))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use instruction::Instruction::*;

    fn compile(text: &'static str) -> Result<Vec<Instruction<'static>>> {
        TemplateCompiler::new(text).compile()
    }

    #[test]
    fn test_compile_literal() {
        let text = "Test String";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(&Literal(text), &instructions[0]);
    }

    #[test]
    fn test_compile_value() {
        let text = "{ foobar }";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(&Value(vec![PathStep::Name("foobar")]), &instructions[0]);
    }

    #[test]
    fn test_compile_value_with_formatter() {
        let text = "{ foobar | my_formatter }";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(
            &FormattedValue(vec![PathStep::Name("foobar")], "my_formatter"),
            &instructions[0]
        );
    }

    #[test]
    fn test_dotted_path() {
        let text = "{ foo.bar }";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(
            &Value(vec![PathStep::Name("foo"), PathStep::Name("bar")]),
            &instructions[0]
        );
    }

    #[test]
    fn test_indexed_path() {
        let text = "{ foo.0.bar }";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(
            &Value(vec![
                PathStep::Name("foo"),
                PathStep::Index("0", 0),
                PathStep::Name("bar")
            ]),
            &instructions[0]
        );
    }

    #[test]
    fn test_mixture() {
        let text = "Hello { name }, how are you?";
        let instructions = compile(text).unwrap();
        assert_eq!(3, instructions.len());
        assert_eq!(&Literal("Hello "), &instructions[0]);
        assert_eq!(&Value(vec![PathStep::Name("name")]), &instructions[1]);
        assert_eq!(&Literal(", how are you?"), &instructions[2]);
    }

    #[test]
    fn test_if_endif() {
        let text = "{{ if foo }}Hello!{{ endif }}";
        let instructions = compile(text).unwrap();
        assert_eq!(2, instructions.len());
        assert_eq!(
            &Branch(vec![PathStep::Name("foo")], true, 2),
            &instructions[0]
        );
        assert_eq!(&Literal("Hello!"), &instructions[1]);
    }

    #[test]
    fn test_if_not_endif() {
        let text = "{{ if not foo }}Hello!{{ endif }}";
        let instructions = compile(text).unwrap();
        assert_eq!(2, instructions.len());
        assert_eq!(
            &Branch(vec![PathStep::Name("foo")], false, 2),
            &instructions[0]
        );
        assert_eq!(&Literal("Hello!"), &instructions[1]);
    }

    #[test]
    fn test_if_else_endif() {
        let text = "{{ if foo }}Hello!{{ else }}Goodbye!{{ endif }}";
        let instructions = compile(text).unwrap();
        assert_eq!(4, instructions.len());
        assert_eq!(
            &Branch(vec![PathStep::Name("foo")], true, 3),
            &instructions[0]
        );
        assert_eq!(&Literal("Hello!"), &instructions[1]);
        assert_eq!(&Goto(4), &instructions[2]);
        assert_eq!(&Literal("Goodbye!"), &instructions[3]);
    }

    #[test]
    fn test_with() {
        let text = "{{ with foo as bar }}Hello!{{ endwith }}";
        let instructions = compile(text).unwrap();
        assert_eq!(3, instructions.len());
        assert_eq!(
            &PushNamedContext(vec![PathStep::Name("foo")], "bar"),
            &instructions[0]
        );
        assert_eq!(&Literal("Hello!"), &instructions[1]);
        assert_eq!(&PopContext, &instructions[2]);
    }

    #[test]
    fn test_foreach() {
        let text = "{{ for foo in bar.baz }}{ foo }{{ endfor }}";
        let instructions = compile(text).unwrap();
        assert_eq!(5, instructions.len());
        assert_eq!(
            &PushIterationContext(vec![PathStep::Name("bar"), PathStep::Name("baz")], "foo"),
            &instructions[0]
        );
        assert_eq!(&Iterate(4), &instructions[1]);
        assert_eq!(&Value(vec![PathStep::Name("foo")]), &instructions[2]);
        assert_eq!(&Goto(1), &instructions[3]);
        assert_eq!(&PopContext, &instructions[4]);
    }

    #[test]
    fn test_strip_whitespace_value() {
        let text = "Hello,     {- name -}   , how are you?";
        let instructions = compile(text).unwrap();
        assert_eq!(3, instructions.len());
        assert_eq!(&Literal("Hello,"), &instructions[0]);
        assert_eq!(&Value(vec![PathStep::Name("name")]), &instructions[1]);
        assert_eq!(&Literal(", how are you?"), &instructions[2]);
    }

    #[test]
    fn test_strip_whitespace_block() {
        let text = "Hello,     {{- if name -}}    {name}    {{- endif -}}   , how are you?";
        let instructions = compile(text).unwrap();
        assert_eq!(6, instructions.len());
        assert_eq!(&Literal("Hello,"), &instructions[0]);
        assert_eq!(
            &Branch(vec![PathStep::Name("name")], true, 5),
            &instructions[1]
        );
        assert_eq!(&Literal(""), &instructions[2]);
        assert_eq!(&Value(vec![PathStep::Name("name")]), &instructions[3]);
        assert_eq!(&Literal(""), &instructions[4]);
        assert_eq!(&Literal(", how are you?"), &instructions[5]);
    }

    #[test]
    fn test_comment() {
        let text = "Hello, {# foo bar baz #} there!";
        let instructions = compile(text).unwrap();
        assert_eq!(2, instructions.len());
        assert_eq!(&Literal("Hello, "), &instructions[0]);
        assert_eq!(&Literal(" there!"), &instructions[1]);
    }

    #[test]
    fn test_strip_whitespace_comment() {
        let text = "Hello, \t\n    {#- foo bar baz -#} \t  there!";
        let instructions = compile(text).unwrap();
        assert_eq!(2, instructions.len());
        assert_eq!(&Literal("Hello,"), &instructions[0]);
        assert_eq!(&Literal("there!"), &instructions[1]);
    }

    #[test]
    fn test_strip_whitespace_followed_by_another_tag() {
        let text = "{value -}{value} Hello";
        let instructions = compile(text).unwrap();
        assert_eq!(3, instructions.len());
        assert_eq!(&Value(vec![PathStep::Name("value")]), &instructions[0]);
        assert_eq!(&Value(vec![PathStep::Name("value")]), &instructions[1]);
        assert_eq!(&Literal(" Hello"), &instructions[2]);
    }

    #[test]
    fn test_call() {
        let text = "{{ call my_macro with foo.bar }}";
        let instructions = compile(text).unwrap();
        assert_eq!(1, instructions.len());
        assert_eq!(
            &Call(
                "my_macro",
                vec![PathStep::Name("foo"), PathStep::Name("bar")]
            ),
            &instructions[0]
        );
    }

    #[test]
    fn test_curly_brace_escaping() {
        let text = "body \\{ \nfont-size: {fontsize} \n}";
        let instructions = compile(text).unwrap();
        assert_eq!(4, instructions.len());
        assert_eq!(&Literal("body "), &instructions[0]);
        assert_eq!(&Literal("{ \nfont-size: "), &instructions[1]);
        assert_eq!(&Value(vec![PathStep::Name("fontsize")]), &instructions[2]);
        assert_eq!(&Literal(" \n}"), &instructions[3]);
    }

    #[test]
    fn test_unclosed_tags() {
        let tags = vec![
            "{",
            "{ foo.bar",
            "{ foo.bar\n }",
            "{{",
            "{{ if foo.bar",
            "{{ if foo.bar \n}}",
            "{#",
            "{# if foo.bar",
            "{# if foo.bar \n#}",
        ];
        for tag in tags {
            compile(tag).unwrap_err();
        }
    }

    #[test]
    fn test_mismatched_blocks() {
        let text = "{{ if foo }}{{ with bar }}{{ endif }} {{ endwith }}";
        compile(text).unwrap_err();
    }

    #[test]
    fn test_disallows_invalid_keywords() {
        let text = "{ @foo }";
        compile(text).unwrap_err();
    }

    #[test]
    fn test_diallows_unknown_block_type() {
        let text = "{{ foobar }}";
        compile(text).unwrap_err();
    }

    #[test]
    fn test_parse_error_line_column_num() {
        let text = "\n\n\n{{ foobar }}";
        let err = compile(text).unwrap_err();
        if let ParseError { line, column, .. } = err {
            assert_eq!(4, line);
            assert_eq!(3, column);
        } else {
            panic!("Should have returned a parse error");
        }
    }

    #[test]
    fn test_parse_error_on_unclosed_if() {
        let text = "{{ if foo }}";
        compile(text).unwrap_err();
    }

    #[test]
    fn test_parse_escaped_open_curly_brace() {
        let text: &str = r"hello \{world}";
        let instructions = compile(text).unwrap();
        assert_eq!(2, instructions.len());
        assert_eq!(&Literal("hello "), &instructions[0]);
        assert_eq!(&Literal("{world}"), &instructions[1]);
    }
}
