// 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.

List sorted(Iterable input, [compare, key]) {
  comparator(compare, key) {
    if (compare == null && key == null)
      return (a, b) => a.compareTo(b);
    if (compare == null)
      return (a, b) => key(a).compareTo(key(b));
    if (key == null)
      return compare;
    return (a, b) => compare(key(a), key(b));
  }
  List copy = new List.from(input);
  copy.sort(comparator(compare, key));
  return copy;
}

render(idl_node, [indent_str='  ']) {
  var output = [''];
  var indent_stack = [];

  indented(action) {  // TODO: revert to  indented(action()) {
    indent_stack.add(indent_str);
    action();
    indent_stack.removeLast();
  }

  sort(nodes) => sorted(nodes, key: (a) => a.id);

  var w; // For some reason mutually recursive local functions don't work.

  wln([node]) {
    w(node);
    output.add('\n');
  }

  w = (node, [list_separator]) {
    /*
     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 == null) {
      return;
    } else if (node is String) {
      if (output.last().endsWith('\n'))
        output.addAll(indent_stack);
      output.add(node);
    } else if (node is List) {
      var separator = null;
      for (var element in node) {
        w(separator);
        separator = list_separator;
        w(element);
      }
    } else if (node is IDLFile) {
      w(node.modules);
      w(node.interfaces);
    } else if (node is IDLModule) {
      w(node.annotations);
      w(node.extAttrs);
      wln('module ${node.id} {');
      indented(() {
          w(node.interfaces);
          w(node.typedefs);
        });
      wln('};');
    } else if (node is IDLInterface) {
      w(node.annotations);
      w(node.extAttrs);
      w('interface ${node.id}');
      indented(() {
          if (!node.parents.isEmpty()) {
            wln(' :');
            w(node.parents, ',\n');
          }
          wln(' {');
          section(list, comment) {
            if (list != null && !list.isEmpty()) {
              wln();
              wln(comment);
              w(sort(list));
            }
          }
          section(node.constants, '/* Constants */');
          section(node.attributes, '/* Attributes */');
          section(node.operations, '/* Operations */');
          section(node.snippets, '/* Snippets */');
        });
      wln('};');
    } else if (node is IDLParentInterface) {
      w(node.annotations);
      w(node.type.id);
    } else if (node is IDLAnnotations) {
      for (var name in sorted(node.map.getKeys())) {
        IDLAnnotation annotation = node.map[name];
        var args = annotation.map;
        if (args.isEmpty()) {
          w('@$name');
        } else {
          var formattedArgs = [];
          for (var argName in sorted(args.getKeys())) {
            var argValue = args[argName];
            if (argValue == null)
              formattedArgs.add(argName);
            else
              formattedArgs.add('$argName=$argValue');
          }
          w('@$name(${Strings.join(formattedArgs,',')})');
        }
        w(' ');
      }
    } else if (node is IDLExtAttrs) {
      if(!node.map.isEmpty()) {
        w('[');
        var sep = null;
        for (var name in sorted(node.map.getKeys())) {
          w(sep);
          sep = ', ';
          w(name);
          var value = node.map[name];
          if (value != null) {
            w('=');
            w(value);
          }
        }
        w('] ');
      }
    } else if (node is IDLAttribute) {
      w(node.annotations);
      w(node.extAttrs);
      //if (node.isFcGetter)
      //  w('getter ');
      //if (node.isFcSetter)
      //  w('setter ');
      wln('attribute ${node.type.id} ${node.id};');
    } else if (node is IDLConstant) {
      w(node.annotations);
      w(node.extAttrs);
      wln('const ${node.type.id} ${node.id} = ${node.value};');
    } else if (node is IDLSnippet) {
      w(node.annotations);
      wln('snippet {${node.text}};');
    } else if (node is IDLOperation) {
      w(node.annotations);
      w(node.extAttrs);
      if (node.specials != null && !node.specials.isEmpty()) {
        w(node.specials, ' ');
        w(' ');
      }
      w('${node.type.id} ${node.id}');
      w('(');
      w(node.arguments, ', ');
      wln(');');
    } else if (node is IDLArgument) {
      w(node.extAttrs);
      w('in ');
      if (node.isOptional)
        w('optional ');
      w('${node.type.id} ${node.id}');
    } else if (node is IDLExtAttrFunctionValue) {
      w(node.name);
      w('(');
      w(node.arguments, ', ');
      w(')');
    } else if (node is IDLTypeDef) {
      wln('typedef ${node.type.id} ${node.id};');
    } else {
      w('// $node\n');
    }
  };

  w(idl_node);
  return Strings.concatAll(output);
}
