#!/usr/bin/env python3
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

from idlnode import *


def render(idl_node, indent_str='  '):
    output = []
    indent_stack = []

    def begin_indent():
        indent_stack.append(indent_str)

    def end_indent():
        indent_stack.pop()

    def sort(nodes):
        return sorted(nodes, key=lambda node: node.id)

    def wln(node=None):
        """Writes the given node and adds a new line."""
        w(node)
        output.append('\n')

    def wsp(node):
        """Writes the given node and adds a space if there was output."""
        mark = len(output)
        w(node)
        if mark != len(output):
            w(' ')

    def w(node, list_separator=None):
        """Writes the given node.

    Args:
      node -- a string, IDLNode instance or a list of such.
      list_separator -- if provided, and node is a list,
        list_separator will be written between the list items.
    """
        if node is None:
            return
        elif isinstance(node, str):
            if output and output[-1].endswith('\n'):
                # Auto-indent.
                output.extend(indent_stack)
            output.append(node)
        elif isinstance(node, list):
            for i in range(0, len(node)):
                if i > 0:
                    w(list_separator)
                w(node[i])
        elif isinstance(node, IDLFile):
            w(node.interfaces)
            w(node.enums)
            w(node.typeDefs)
        elif isinstance(node, IDLModule):
            wsp(node.annotations)
            wsp(node.ext_attrs)
            wln('module %s {' % node.id)
            begin_indent()
            w(node.interfaces)
            w(node.enums)
            w(node.typeDefs)
            end_indent()
            wln('};')
        elif isinstance(node, IDLEnum):
            w('enum %s {}' % node.id)
            # TODO(antonm): emit values as well.
        elif isinstance(node, IDLInterface):
            if node.annotations:
                wln(node.annotations)
            if node.ext_attrs:
                wln(node.ext_attrs)
            w('interface %s' % node.id)
            begin_indent()
            begin_indent()
            if node.parents:
                wln(' :')
                w(node.parents, ',\n')
            wln(' {')
            end_indent()
            if node.constants:
                wln()
                wln('/* Constants */')
                w(sort(node.constants))
            if node.attributes:
                wln()
                wln('/* Attributes */')
                w(sort(node.attributes))
            if node.operations:
                wln()
                wln('/* Operations */')
                w(sort(node.operations))
            end_indent()
            wln('};')
        elif isinstance(node, IDLParentInterface):
            wsp(node.annotations)
            w(node.type.id)
        elif isinstance(node, IDLAnnotations):
            sep = ''
            for (name, annotation) in sorted(node.items()):
                w(sep)
                sep = ' '
                if annotation and len(annotation):
                    subRes = []
                    for (argName, argValue) in sorted(annotation.items()):
                        if argValue is None:
                            subRes.append(argName)
                        else:
                            subRes.append('%s=%s' % (argName, argValue))
                    w('@%s(%s)' % (name, ', '.join(subRes)))
                else:
                    w('@%s' % name)
        elif isinstance(node, IDLExtAttrs):
            if len(node):
                w('[')
                i = 0
                for k in sorted(node):
                    if i > 0:
                        w(', ')
                    w(k)
                    v = node[k]
                    if v is not None:
                        if isinstance(v, IDLExtAttrFunctionValue):
                            if v.id:
                                w('=')
                            w(v)
                        elif isinstance(v, list):
                            assert k == 'Constructor'
                            w(v[0])
                            for c in v[1:]:
                                w(', ')
                                w(k)
                                w(c)
                        else:
                            w('=%s' % v.__str__())
                    i += 1
                w(']')
        elif isinstance(node, IDLExtAttrFunctionValue):
            if node.id:
                w(node.id)
            w('(')
            w(node.arguments, ', ')
            w(')')
        elif isinstance(node, IDLAttribute):
            wsp(node.annotations)
            wsp(node.ext_attrs)
            if node.is_read_only:
                w('readonly ')
            w('attribute ')
            w(node.type.id)
            if (node.type.nullable):
                w('?')
            w(' ')
            w(node.id)
            wln(';')
        elif isinstance(node, IDLConstant):
            wsp(node.annotations)
            wsp(node.ext_attrs)
            wln('const %s %s = %s;' % (node.type.id, node.id, node.value))
        elif isinstance(node, IDLOperation):
            wsp(node.annotations)
            wsp(node.ext_attrs)
            if node.is_static:
                w('static ')
            if node.specials:
                w(node.specials, ' ')
                w(' ')
            w(node.type.id)
            if (node.type.nullable):
                w('?')
            w(' ')
            w(node.id)
            w('(')
            w(node.arguments, ', ')
            w(')')
            wln(';')
        elif isinstance(node, IDLArgument):
            wsp(node.ext_attrs)
            if (node.optional):
                w('optional ')
            w(node.type.id)
            if node.type.nullable:
                w('?')
            w(' %s' % node.id)
        else:
            raise TypeError("Expected str or IDLNode but %s found" % type(node))

    w(idl_node)
    return ''.join(output)
