// 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.keys)) {
        IDLAnnotation annotation = node.map[name];
        var args = annotation.map;
        if (args.isEmpty) {
          w('@$name');
        } else {
          var formattedArgs = [];
          for (var argName in sorted(args.keys)) {
            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.keys)) {
          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);
}
