// Copyright (c) 2012, 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.

part of tree;

String unparse(Node node) {
  Unparser unparser = new Unparser();
  unparser.unparse(node);
  return unparser.result;
}

class Unparser implements Visitor {
  final StringBuffer sb;

  String get result => sb.toString();

  Unparser() : sb = new StringBuffer();

  void add(SourceString string) {
    string.printOn(sb);
  }

  void addToken(Token token) {
    if (token == null) return;
    add(token.value);
    if (identical(token.kind, KEYWORD_TOKEN)
        || identical(token.kind, IDENTIFIER_TOKEN)) {
      sb.write(' ');
    }
  }

  unparse(Node node) { visit(node); }

  visit(Node node) {
    if (node != null) node.accept(this);
  }

  visitBlock(Block node) {
    visit(node.statements);
  }

  visitCascade(Cascade node) {
    visit(node.expression);
  }

  visitCascadeReceiver(CascadeReceiver node) {
    visit(node.expression);
  }

  unparseClassWithBody(ClassNode node, members) {
    addToken(node.beginToken);
    if (node.beginToken.stringValue == 'abstract') {
      addToken(node.beginToken.next);
    }
    visit(node.name);
    if (node.typeParameters != null) {
      visit(node.typeParameters);
    }
    if (node.extendsKeyword != null) {
      sb.write(' ');
      addToken(node.extendsKeyword);
      visit(node.superclass);
    }
    if (!node.interfaces.isEmpty) {
      sb.write(' ');
      visit(node.interfaces);
    }
    sb.write('{');
    for (final member in members) {
      visit(member);
    }
    sb.write('}');
  }

  visitClassNode(ClassNode node) {
    unparseClassWithBody(node, node.body.nodes);
  }

  visitMixinApplication(MixinApplication node) {
    visit(node.superclass);
    sb.write(' with ');
    visit(node.mixins);
  }

  visitNamedMixinApplication(NamedMixinApplication node) {
    sb.write('typedef ');
    visit(node.name);
    if (node.typeParameters != null) {
      visit(node.typeParameters);
    }
    sb.write(' = ');
    if (!node.modifiers.nodes.isEmpty) {
      visit(node.modifiers);
      sb.write(' ');
    }
    visit(node.mixinApplication);
    if (node.interfaces != null) {
      sb.write(' implements ');
      visit(node.interfaces);
    }
    sb.write(';');
  }

  visitConditional(Conditional node) {
    visit(node.condition);
    add(node.questionToken.value);
    visit(node.thenExpression);
    add(node.colonToken.value);
    visit(node.elseExpression);
  }

  visitExpressionStatement(ExpressionStatement node) {
    visit(node.expression);
    add(node.endToken.value);
  }

  visitFor(For node) {
    add(node.forToken.value);
    sb.write('(');
    visit(node.initializer);
    sb.write(';');
    visit(node.conditionStatement);
    visit(node.update);
    sb.write(')');
    visit(node.body);
  }

  visitFunctionDeclaration(FunctionDeclaration node) {
    visit(node.function);
  }

  void unparseFunctionName(Node name) {
    // TODO(antonm): that's a workaround as currently FunctionExpression
    // names are modelled with Send and it emits operator[] as only
    // operator, without [] which are expected to be emitted with
    // arguments.
    if (name is Send) {
      Send send = name;
      assert(send is !SendSet);
      if (!send.isOperator) {
        // Looks like a factory method.
        visit(send.receiver);
        sb.write('.');
      } else {
        visit(send.receiver);
        Identifier identifier = send.selector.asIdentifier();
        if (identical(identifier.token.kind, KEYWORD_TOKEN)) {
          sb.write(' ');
        } else if (identifier.source == const SourceString('negate')) {
          // TODO(ahe): Remove special case for negate.
          sb.write(' ');
        }
      }
      visit(send.selector);
    } else {
      visit(name);
    }
  }

  visitFunctionExpression(FunctionExpression node) {
    if (!node.modifiers.nodes.isEmpty) {
      visit(node.modifiers);
      sb.write(' ');
    }
    if (node.returnType != null) {
      visit(node.returnType);
      sb.write(' ');
    }
    if (node.getOrSet != null) {
      add(node.getOrSet.value);
      sb.write(' ');
    }
    unparseFunctionName(node.name);
    visit(node.parameters);
    visit(node.initializers);
    visit(node.body);
  }

  visitIdentifier(Identifier node) {
    add(node.token.value);
  }

  visitIf(If node) {
    add(node.ifToken.value);
    visit(node.condition);
    visit(node.thenPart);
    if (node.hasElsePart) {
      add(node.elseToken.value);
      if (node.elsePart is !Block) sb.write(' ');
      visit(node.elsePart);
    }
  }

  visitLiteralBool(LiteralBool node) {
    add(node.token.value);
  }

  visitLiteralDouble(LiteralDouble node) {
    add(node.token.value);
    // -Lit is represented as a send.
    if (node.token.kind == PLUS_TOKEN) add(node.token.next.value);
  }

  visitLiteralInt(LiteralInt node) {
    add(node.token.value);
    // -Lit is represented as a send.
    if (node.token.kind == PLUS_TOKEN) add(node.token.next.value);
  }

  visitLiteralString(LiteralString node) {
    add(node.token.value);
  }

  visitStringJuxtaposition(StringJuxtaposition node) {
    visit(node.first);
    sb.write(" ");
    visit(node.second);
  }

  visitLiteralNull(LiteralNull node) {
    add(node.token.value);
  }

  visitNewExpression(NewExpression node) {
    addToken(node.newToken);
    visit(node.send);
  }

  visitLiteralList(LiteralList node) {
    if (node.constKeyword != null) add(node.constKeyword.value);
    visit(node.typeArguments);
    visit(node.elements);
    // If list is empty, emit space after [] to disambiguate cases like []==[].
    if (node.elements.isEmpty) sb.write(' ');
  }

  visitModifiers(Modifiers node) => node.visitChildren(this);

  /**
   * Unparses given NodeList starting from specific node.
   */
  unparseNodeListFrom(NodeList node, Link<Node> from) {
    if (from.isEmpty) return;
    String delimiter = (node.delimiter == null) ? "" : "${node.delimiter}";
    visit(from.head);
    for (Link link = from.tail; !link.isEmpty; link = link.tail) {
      sb.write(delimiter);
      visit(link.head);
    }
  }

  visitNodeList(NodeList node) {
    addToken(node.beginToken);
    if (node.nodes != null) {
      unparseNodeListFrom(node, node.nodes);
    }
    if (node.endToken != null) add(node.endToken.value);
  }

  visitOperator(Operator node) {
    visitIdentifier(node);
  }

  visitRethrow(Rethrow node) {
    sb.write('rethrow;');
  }

  visitReturn(Return node) {
    if (node.isRedirectingFactoryBody) {
      sb.write(' ');
    }
    add(node.beginToken.value);
    if (node.hasExpression && node.beginToken.stringValue != '=>') {
      sb.write(' ');
    }
    visit(node.expression);
    if (node.endToken != null) add(node.endToken.value);
  }

  unparseSendReceiver(Send node, {bool spacesNeeded: false}) {
    if (node.receiver == null) return;
    visit(node.receiver);
    CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver();
    if (asCascadeReceiver != null) {
      add(asCascadeReceiver.cascadeOperator.value);
    } else if (node.selector.asOperator() == null) {
      sb.write('.');
    } else if (spacesNeeded) {
      sb.write(' ');
    }
  }

  visitSend(Send node) {
    Operator op = node.selector.asOperator();
    String opString = op != null ? op.source.stringValue : null;
    bool spacesNeeded = identical(opString, 'is') || identical(opString, 'as');

    if (node.isPrefix) visit(node.selector);
    unparseSendReceiver(node, spacesNeeded: spacesNeeded);
    if (!node.isPrefix && !node.isIndex) visit(node.selector);
    if (spacesNeeded) sb.write(' ');
    // Also add a space for sequences like x + +1 and y - -y.
    // TODO(ahe): remove case for '+' when we drop the support for it.
    if (node.argumentsNode != null && (identical(opString, '-')
        || identical(opString, '+'))) {
      Token beginToken = node.argumentsNode.getBeginToken();
      if (beginToken != null && identical(beginToken.stringValue, opString)) {
        sb.write(' ');
      }
    }
    visit(node.argumentsNode);
  }

  visitSendSet(SendSet node) {
    if (node.isPrefix) {
      sb.write(' ');
      visit(node.assignmentOperator);
    }
    unparseSendReceiver(node);
    if (node.isIndex) {
      sb.write('[');
      visit(node.arguments.head);
      sb.write(']');
      if (!node.isPrefix) visit(node.assignmentOperator);
      unparseNodeListFrom(node.argumentsNode, node.argumentsNode.nodes.tail);
    } else {
      visit(node.selector);
      if (!node.isPrefix) {
        visit(node.assignmentOperator);
        if (node.assignmentOperator.source.slowToString() != '=') sb.write(' ');
      }
      visit(node.argumentsNode);
    }
  }

  visitThrow(Throw node) {
    add(node.throwToken.value);
    sb.write(' ');
    visit(node.expression);
  }

  visitTypeAnnotation(TypeAnnotation node) {
    visit(node.typeName);
    visit(node.typeArguments);
  }

  visitTypeVariable(TypeVariable node) {
    visit(node.name);
    if (node.bound != null) {
      sb.write(' extends ');
      visit(node.bound);
    }
  }

  visitVariableDefinitions(VariableDefinitions node) {
    visit(node.modifiers);
    if (!node.modifiers.nodes.isEmpty) {
      sb.write(' ');
    }
    if (node.type != null) {
      visit(node.type);
      sb.write(' ');
    }
    visit(node.definitions);
  }

  visitDoWhile(DoWhile node) {
    add(node.doKeyword.value);
    if (node.body is !Block) sb.write(' ');
    visit(node.body);
    add(node.whileKeyword.value);
    visit(node.condition);
    sb.write(node.endToken.value);
  }

  visitWhile(While node) {
    addToken(node.whileKeyword);
    visit(node.condition);
    visit(node.body);
  }

  visitParenthesizedExpression(ParenthesizedExpression node) {
    add(node.getBeginToken().value);
    visit(node.expression);
    add(node.getEndToken().value);
  }

  visitStringInterpolation(StringInterpolation node) {
    visit(node.string);
    visit(node.parts);
  }

  visitStringInterpolationPart(StringInterpolationPart node) {
    sb.write('\${'); // TODO(ahe): Preserve the real tokens.
    visit(node.expression);
    sb.write('}');
    visit(node.string);
  }

  visitEmptyStatement(EmptyStatement node) {
    add(node.semicolonToken.value);
  }

  visitGotoStatement(GotoStatement node) {
    add(node.keywordToken.value);
    if (node.target != null) {
      sb.write(' ');
      visit(node.target);
    }
    add(node.semicolonToken.value);
  }

  visitBreakStatement(BreakStatement node) {
    visitGotoStatement(node);
  }

  visitContinueStatement(ContinueStatement node) {
    visitGotoStatement(node);
  }

  visitForIn(ForIn node) {
    add(node.forToken.value);
    sb.write('(');
    visit(node.declaredIdentifier);
    sb.write(' ');
    addToken(node.inToken);
    visit(node.expression);
    sb.write(')');
    visit(node.body);
  }

  visitLabel(Label node) {
    visit(node.identifier);
    add(node.colonToken.value);
   }

  visitLabeledStatement(LabeledStatement node) {
    visit(node.labels);
    visit(node.statement);
  }

  visitLiteralMap(LiteralMap node) {
    if (node.constKeyword != null) add(node.constKeyword.value);
    if (node.typeArguments != null) visit(node.typeArguments);
    visit(node.entries);
  }

  visitLiteralMapEntry(LiteralMapEntry node) {
    visit(node.key);
    add(node.colonToken.value);
    visit(node.value);
  }

  visitNamedArgument(NamedArgument node) {
    visit(node.name);
    add(node.colonToken.value);
    visit(node.expression);
  }

  visitSwitchStatement(SwitchStatement node) {
    addToken(node.switchKeyword);
    visit(node.parenthesizedExpression);
    visit(node.cases);
  }

  visitSwitchCase(SwitchCase node) {
    visit(node.labelsAndCases);
    if (node.isDefaultCase) {
      sb.write('default:');
    }
    visit(node.statements);
  }

  unparseImportTag(String uri, [String prefix]) {
    final suffix = prefix == null ? '' : ' as $prefix';
    sb.write('import "$uri"$suffix;');
  }

  visitScriptTag(ScriptTag node) {
    add(node.beginToken.value);
    visit(node.tag);
    sb.write('(');
    visit(node.argument);
    if (node.prefixIdentifier != null) {
      visit(node.prefixIdentifier);
      sb.write(':');
      visit(node.prefix);
    }
    sb.write(')');
    add(node.endToken.value);
  }

  visitTryStatement(TryStatement node) {
    addToken(node.tryKeyword);
    visit(node.tryBlock);
    visit(node.catchBlocks);
    if (node.finallyKeyword != null) {
      addToken(node.finallyKeyword);
      visit(node.finallyBlock);
    }
  }

  visitCaseMatch(CaseMatch node) {
    add(node.caseKeyword.value);
    sb.write(" ");
    visit(node.expression);
    add(node.colonToken.value);
  }

  visitCatchBlock(CatchBlock node) {
    addToken(node.onKeyword);
    if (node.type != null) {
      visit(node.type);
      sb.write(' ');
    }
    addToken(node.catchKeyword);
    visit(node.formals);
    visit(node.block);
  }

  visitTypedef(Typedef node) {
    addToken(node.typedefKeyword);
    if (node.returnType != null) {
      visit(node.returnType);
      sb.write(' ');
    }
    visit(node.name);
    if (node.typeParameters != null) {
      visit(node.typeParameters);
    }
    visit(node.formals);
    add(node.endToken.value);
  }

  visitLibraryName(LibraryName node) {
    addToken(node.libraryKeyword);
    node.visitChildren(this);
    add(node.getEndToken().value);
  }

  visitImport(Import node) {
    addToken(node.importKeyword);
    visit(node.uri);
    if (node.prefix != null) {
      sb.write(' ');
      addToken(node.asKeyword);
      visit(node.prefix);
    }
    if (node.combinators != null) {
      sb.write(' ');
      visit(node.combinators);
    }
    add(node.getEndToken().value);
  }

  visitExport(Export node) {
    addToken(node.exportKeyword);
    visit(node.uri);
    if (node.combinators != null) {
      sb.write(' ');
      visit(node.combinators);
    }
    add(node.getEndToken().value);
  }

  visitPart(Part node) {
    addToken(node.partKeyword);
    visit(node.uri);
    add(node.getEndToken().value);
  }

  visitPartOf(PartOf node) {
    addToken(node.partKeyword);
    addToken(node.ofKeyword);
    visit(node.name);
    add(node.getEndToken().value);
  }

  visitCombinator(Combinator node) {
    addToken(node.keywordToken);
    visit(node.identifiers);
  }

  visitNode(Node node) {
    throw 'internal error'; // Should not be called.
  }

  visitExpression(Expression node) {
    throw 'internal error'; // Should not be called.
  }

  visitLibraryTag(LibraryTag node) {
    throw 'internal error'; // Should not be called.
  }

  visitLibraryDependency(Node node) {
    throw 'internal error'; // Should not be called.
  }

  visitLiteral(Literal node) {
    throw 'internal error'; // Should not be called.
  }

  visitLoop(Loop node) {
    throw 'internal error'; // Should not be called.
  }

  visitPostfix(Postfix node) {
    throw 'internal error'; // Should not be called.
  }

  visitPrefix(Prefix node) {
    throw 'internal error'; // Should not be called.
  }

  visitStatement(Statement node) {
    throw 'internal error'; // Should not be called.
  }

  visitStringNode(StringNode node) {
    throw 'internal error'; // Should not be called.
  }
}
