# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import unittest

from .code_node import ListNode
from .code_node import LiteralNode
from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
from .code_node import WeakDependencyNode
from .code_node import render_code_node
from .codegen_accumulator import CodeGenAccumulator
from .mako_renderer import MakoRenderer


class CodeNodeTest(unittest.TestCase):
    def setUp(self):
        super(CodeNodeTest, self).setUp()
        self.addTypeEqualityFunc(str, self.assertMultiLineEqual)

    def assertRenderResult(self, node, expected):
        if node.renderer is None:
            node.set_renderer(MakoRenderer())
        if node.accumulator is None:
            node.set_accumulator(CodeGenAccumulator())

        def simplify(text):
            return "\n".join(
                [" ".join(line.split()) for line in text.split("\n")])

        actual = simplify(render_code_node(node))
        expected = simplify(expected)

        self.assertEqual(actual, expected)

    def test_literal_node(self):
        """
        Tests that, in LiteralNode, the special characters of template (%, ${},
        etc) are not processed.
        """
        root = LiteralNode("<% x = 42 %>${x}")
        self.assertRenderResult(root, "<% x = 42 %>${x}")

    def test_empty_literal_node(self):
        root = LiteralNode("")
        self.assertRenderResult(root, "")

    def test_text_node(self):
        """Tests that the template language works in TextNode."""
        root = TextNode("<% x = 42 %>${x}")
        self.assertRenderResult(root, "42")

    def test_empty_text_node(self):
        root = TextNode("")
        self.assertRenderResult(root, "")

    def test_list_operations_of_sequence_node(self):
        """
        Tests that list operations (insert, append, and extend) of ListNode
        work just same as Python built-in list.
        """
        root = ListNode(separator=",")
        root.extend([
            LiteralNode("2"),
            LiteralNode("4"),
        ])
        root.insert(1, LiteralNode("3"))
        root.insert(0, LiteralNode("1"))
        root.insert(100, LiteralNode("5"))
        root.append(LiteralNode("6"))
        self.assertRenderResult(root, "1,2,3,4,5,6")
        root.remove(root[0])
        root.remove(root[2])
        root.remove(root[-1])
        self.assertRenderResult(root, "2,3,5")

    def test_list_node_head_and_tail(self):
        self.assertRenderResult(ListNode(), "")
        self.assertRenderResult(ListNode(head="head"), "")
        self.assertRenderResult(ListNode(tail="tail"), "")
        self.assertRenderResult(
            ListNode([TextNode("-content-")], head="head", tail="tail"),
            "head-content-tail")

    def test_nested_sequence(self):
        """Tests nested ListNodes."""
        root = ListNode(separator=",")
        nested = ListNode(separator=",")
        nested.extend([
            LiteralNode("2"),
            LiteralNode("3"),
            LiteralNode("4"),
        ])
        root.extend([
            LiteralNode("1"),
            nested,
            LiteralNode("5"),
        ])
        self.assertRenderResult(root, "1,2,3,4,5")

    def test_symbol_definition_chains(self):
        """
        Tests that use of SymbolNode inserts necessary SymbolDefinitionNode
        appropriately.
        """
        root = SymbolScopeNode(tail="\n")

        root.register_code_symbols([
            SymbolNode("var1", "int ${var1} = ${var2} + ${var3};"),
            SymbolNode("var2", "int ${var2} = ${var5};"),
            SymbolNode("var3", "int ${var3} = ${var4};"),
            SymbolNode("var4", "int ${var4} = 1;"),
            SymbolNode("var5", "int ${var5} = 2;"),
        ])

        root.append(TextNode("(void)${var1};"))

        self.assertRenderResult(
            root, """\
int var5 = 2;
int var2 = var5;
int var4 = 1;
int var3 = var4;
int var1 = var2 + var3;
(void)var1;
""")

    def test_weak_dependency_node(self):
        root = SymbolScopeNode(tail="\n")

        root.register_code_symbols([
            SymbolNode("var1", "int ${var1} = 1;"),
            SymbolNode("var2", "int ${var2} = 2;"),
            SymbolNode("var3", "int ${var3} = 3;"),
        ])

        root.extend([
            WeakDependencyNode(dep_syms=["var1", "var2"]),
            TextNode("f();"),
            TextNode("(void)${var3};"),
            TextNode("(void)${var1};"),
        ])

        self.assertRenderResult(
            root, """\
int var1 = 1;

f();
int var3 = 3;
(void)var3;
(void)var1;
""")

    def test_template_error_handling(self):
        renderer = MakoRenderer()
        root = SymbolScopeNode()
        root.set_renderer(renderer)

        root.append(
            SymbolScopeNode([
                # Have Mako raise a NameError.
                TextNode("${unbound_symbol}"),
            ]))

        with self.assertRaises(NameError):
            renderer.reset()
            root.render(renderer)

        callers_on_error = list(renderer.callers_on_error)
        self.assertEqual(len(callers_on_error), 3)
        self.assertEqual(callers_on_error[0], root[0][0])
        self.assertEqual(callers_on_error[1], root[0])
        self.assertEqual(callers_on_error[2], root)
        self.assertEqual(renderer.last_caller_on_error, root[0][0])
