from node import NodeVisitor, ValueNode, ListNode, BinaryExpressionNode
from parser import atoms, precedence

atom_names = {v:"@%s" % k for (k,v) in atoms.items()}

named_escapes = set(["\a", "\b", "\f", "\n", "\r", "\t", "\v"])

def escape(string, extras=""):
    rv = ""
    for c in string:
        if c in named_escapes:
            rv += c.encode("unicode_escape")
        elif c == "\\":
            rv += "\\\\"
        elif c < '\x20':
            rv += "\\x%02x" % ord(c)
        elif c in extras:
            rv += "\\" + c
        else:
            rv += c
    return rv.encode("utf8")


class ManifestSerializer(NodeVisitor):
    def __init__(self, skip_empty_data=False):
        self.skip_empty_data = skip_empty_data

    def serialize(self, root):
        self.indent = 2
        rv = "\n".join(self.visit(root))
        if rv[-1] != "\n":
            rv = rv + "\n"
        return rv

    def visit_DataNode(self, node):
        rv = []
        if not self.skip_empty_data or node.children:
            if node.data:
                rv.append("[%s]" % escape(node.data, extras="]"))
                indent = self.indent * " "
            else:
                indent = ""

            for child in node.children:
                rv.extend("%s%s" % (indent if item else "", item) for item in self.visit(child))

            if node.parent:
                rv.append("")

        return rv

    def visit_KeyValueNode(self, node):
        rv = [escape(node.data, ":") + ":"]
        indent = " " * self.indent

        if len(node.children) == 1 and isinstance(node.children[0], (ValueNode, ListNode)):
            rv[0] += " %s" % self.visit(node.children[0])[0]
        else:
            for child in node.children:
                rv.append(indent + self.visit(child)[0])

        return rv

    def visit_ListNode(self, node):
        rv = ["["]
        rv.extend(", ".join(self.visit(child)[0] for child in node.children))
        rv.append("]")
        return ["".join(rv)]

    def visit_ValueNode(self, node):
        if "#" in node.data or (isinstance(node.parent, ListNode) and
                                ("," in node.data or "]" in node.data)):
            if "\"" in node.data:
                quote = "'"
            else:
                quote = "\""
        else:
            quote = ""
        return [quote + escape(node.data, extras=quote) + quote]

    def visit_AtomNode(self, node):
        return [atom_names[node.data]]

    def visit_ConditionalNode(self, node):
        return ["if %s: %s" % tuple(self.visit(item)[0] for item in node.children)]

    def visit_StringNode(self, node):
        rv = ["\"%s\"" % escape(node.data, extras="\"")]
        for child in node.children:
            rv[0] += self.visit(child)[0]
        return rv

    def visit_NumberNode(self, node):
        return [str(node.data)]

    def visit_VariableNode(self, node):
        rv = escape(node.data)
        for child in node.children:
            rv += self.visit(child)
        return [rv]

    def visit_IndexNode(self, node):
        assert len(node.children) == 1
        return ["[%s]" % self.visit(node.children[0])[0]]

    def visit_UnaryExpressionNode(self, node):
        children = []
        for child in node.children:
            child_str = self.visit(child)[0]
            if isinstance(child, BinaryExpressionNode):
                child_str = "(%s)" % child_str
            children.append(child_str)
        return [" ".join(children)]

    def visit_BinaryExpressionNode(self, node):
        assert len(node.children) == 3
        children = []
        for child_index in [1, 0, 2]:
            child = node.children[child_index]
            child_str = self.visit(child)[0]
            if (isinstance(child, BinaryExpressionNode) and
                precedence(node.children[0]) < precedence(child.children[0])):
                child_str = "(%s)" % child_str
            children.append(child_str)
        return [" ".join(children)]

    def visit_UnaryOperatorNode(self, node):
        return [str(node.data)]

    def visit_BinaryOperatorNode(self, node):
        return [str(node.data)]


def serialize(tree, *args, **kwargs):
    s = ManifestSerializer(*args, **kwargs)
    return s.serialize(tree)
