// 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, {minify: true}) {
  Unparser unparser = new Unparser(minify: minify);
  unparser.unparse(node);
  return unparser.result;
}

class Unparser extends Indentation implements Visitor {
  final StringBuffer sb = new StringBuffer();

  String get result => sb.toString();

  Unparser({this.minify: true, this.stripTypes: false});

  bool minify;
  bool stripTypes;

  void newline() {
    if (!minify) {
      sb.write("\n");
      onEmptyLine = true;
    }
  }

  void space([String token = " "]) {
    write(minify ? "" : token);
  }

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

  bool onEmptyLine = true;

  write(object) {
    String s = object.toString();
    if (s == '') return;
    if (onEmptyLine) {
      sb.write(indentation);
    }
    sb.write(s);
    onEmptyLine = false;
  }

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

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

  visitBlock(Block node) => unparseBlockStatements(node.statements);

  unparseBlockStatements(NodeList statements) {
    addToken(statements.beginToken);

    Link<Node> nodes = statements.nodes;
    if (nodes != null && !nodes.isEmpty) {
      indentMore();
      newline();
      visit(nodes.head);
      for (Link link = nodes.tail; !link.isEmpty; link = link.tail) {
        newline();
        visit(link.head);
      }
      indentLess();
      newline();
    }
    if (statements.endToken != null) {
      write(statements.endToken.value);
    }
  }


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

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

  unparseClassWithBody(ClassNode node, members) {
    if (!node.modifiers.nodes.isEmpty) {
      visit(node.modifiers);
      write(' ');
    }
    write('class ');
    visit(node.name);
    if (node.typeParameters != null) {
      visit(node.typeParameters);
    }
    if (node.extendsKeyword != null) {
      write(' ');
      addToken(node.extendsKeyword);
      visit(node.superclass);
    }
    if (!node.interfaces.isEmpty) {
      write(' ');
      visit(node.interfaces);
    }
    space();
    write('{');
    if (!members.isEmpty) {
      newline();
      indentMore();
      for (Node member in members) {
        visit(member);
        newline();
      }
      indentLess();
    }
    write('}');
  }

  visitEnum(Enum node) {
    sb.write('enum ');
    visit(node.name);
    sb.write(' ');
    visit(node.names);
  }

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

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

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

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

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

  visitFor(For node) {
    write(node.forToken.value);
    space();
    write('(');
    visit(node.initializer);
    write(';');
    if (node.conditionStatement is! EmptyStatement) space();
    visit(node.conditionStatement);
    if (!node.update.nodes.isEmpty) space();
    visit(node.update);
    write(')');
    space();
    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);
        write('.');
      } else {
        visit(send.receiver);
        Identifier identifier = send.selector.asIdentifier();
        if (identical(identifier.token.kind, KEYWORD_TOKEN)) {
          write(' ');
        } else if (identifier.source == 'negate') {
          // TODO(ahe): Remove special case for negate.
          write(' ');
        }
      }
      visit(send.selector);
    } else {
      visit(name);
    }
  }

  visitAsyncModifier(AsyncModifier node) {
    write(node.asyncToken.value);
    if (node.starToken != null) {
      write(node.starToken.value);
    }
  }

  visitFunctionExpression(FunctionExpression node) {
    if (!node.modifiers.nodes.isEmpty) {
      visit(node.modifiers);
      write(' ');
    }
    if (node.returnType != null && !stripTypes) {
      visit(node.returnType);
      write(' ');
    }
    if (node.getOrSet != null) {
      write(node.getOrSet.value);
      write(' ');
    }
    unparseFunctionName(node.name);
    visit(node.parameters);
    if (node.initializers != null) {
      space();
      write(':');
      space();
      unparseNodeListFrom(node.initializers, node.initializers.nodes,
          spaces: true);
    }
    if (node.asyncModifier != null) {
      if (node.getOrSet != null) {
        write(' ');
      } else {
        // Space is optional if this is not a getter.
        space();
      }
      visit(node.asyncModifier);
    }
    if (node.body != null && node.body is! EmptyStatement) {
      space();
    }
    visit(node.body);
  }

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

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

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

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

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

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

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

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

  visitLiteralSymbol(LiteralSymbol node) {
    write(node.hashToken.value);
    unparseNodeListOfIdentifiers(node.identifiers);
  }

  unparseNodeListOfIdentifiers(NodeList node) {
    // Manually print the list to avoid spaces around operators in unminified
    // code.
    Link<Node> l = node.nodes;
    write(l.head.asIdentifier().token.value);
    for (l = l.tail; !l.isEmpty; l = l.tail) {
      write(".");
      write(l.head.asIdentifier().token.value);
    }
  }

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

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

  visitModifiers(Modifiers node) {
    // Spaces are already included as delimiter.
    unparseNodeList(node.nodes, spaces: false);
  }

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

  unparseNodeList(NodeList node, {bool spaces: true}) {
    addToken(node.beginToken);
    if (node.nodes != null) {
      unparseNodeListFrom(node, node.nodes, spaces: spaces);
    }
    if (node.endToken != null) write(node.endToken.value);
  }

  visitNodeList(NodeList node) {
    unparseNodeList(node);
  }

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

  visitRedirectingFactoryBody(RedirectingFactoryBody node) {
    space();
    write(node.beginToken.value);
    space();
    visit(node.constructorReference);
    write(node.endToken.value);
  }

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

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

  visitYield(Yield node) {
    write(node.yieldToken.value);
    if (node.starToken != null) {
      write(node.starToken.value);
    }
    write(' ');
    visit(node.expression);
    write(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) {
      newline();
      indentMore();
      indentMore();
      write(asCascadeReceiver.cascadeOperator.value);
      indentLess();
      indentLess();
    } else if (node.selector.asOperator() == null) {
      write(node.isConditional ? '?.' : '.');
    } else if (spacesNeeded) {
      write(' ');
    }
  }

  unparseSendArgument(Send node, {bool spacesNeeded: false}) {
    if (node.argumentsNode == null) return;

    if(node.isIsNotCheck) {
      Send argNode = node.arguments.head;
      visit(argNode.selector);
      space();
      visit(argNode.receiver);
    } else {
      if (spacesNeeded) write(' ');
      visit(node.argumentsNode);
    }
  }

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

    void minusMinusSpace(Node other) {
      if (other != null && opString == '-') {
        Token beginToken = other.getBeginToken();
        if (beginToken != null && beginToken.stringValue != null && beginToken.stringValue.startsWith('-')) {
          sb.write(' ');
          spacesNeeded = false;
        }
      }
    }

    if (node.isPrefix) {
      visit(node.selector);
      // Add a space for sequences like - -x (double unary minus).
      minusMinusSpace(node.receiver);
    }

    unparseSendReceiver(node, spacesNeeded: spacesNeeded);
    if (!node.isPrefix && !node.isIndex) {
      visit(node.selector);
    }
    minusMinusSpace(node.argumentsNode);

    unparseSendArgument(node, spacesNeeded: spacesNeeded);
  }

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

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

  visitAwait(Await node) {
    write(node.awaitToken.value);
    write(' ');
    visit(node.expression);
  }

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

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

  visitVariableDefinitions(VariableDefinitions node) {
    if (node.metadata != null) {
      visit(node.metadata);
      write(' ');
    }
    visit(node.modifiers);
    if (!node.modifiers.nodes.isEmpty) {
      write(' ');
    }
    // TODO(sigurdm): Avoid writing the space when [stripTypes], but still write
    // it if the 'type; is var.
    if (node.type != null) {
      visit(node.type);
      write(' ');
    }
    visit(node.definitions);
  }

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

  visitWhile(While node) {
    write(node.whileKeyword.value);
    space();
    visit(node.condition);
    space();
    visit(node.body);
  }

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

  visitStringInterpolation(StringInterpolation node) {
    visit(node.string);
    unparseNodeList(node.parts, spaces: false);
  }

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

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

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

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

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

  visitAsyncForIn(AsyncForIn node) {
    write(node.awaitToken.value);
    write(' ');
    write(node.forToken.value);
    space();
    write('(');
    visit(node.declaredIdentifier);
    write(' ');
    addToken(node.inToken);
    visit(node.expression);
    write(')');
    space();
    visit(node.body);
  }


  visitSyncForIn(SyncForIn node) {
    write(node.forToken.value);
    space();
    write('(');
    visit(node.declaredIdentifier);
    write(' ');
    addToken(node.inToken);
    visit(node.expression);
    write(')');
    space();
    visit(node.body);
  }

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

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

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

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

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

  visitSwitchStatement(SwitchStatement node) {
    addToken(node.switchKeyword);
    visit(node.parenthesizedExpression);
    space();
    unparseNodeList(node.cases, spaces: false);
  }

  visitSwitchCase(SwitchCase node) {
    newline();
    indentMore();
    visit(node.labelsAndCases);
    if (node.isDefaultCase) {
      write('default:');
    }
    unparseBlockStatements(node.statements);
    indentLess();
  }

  unparseImportTag(String uri, {String prefix,
                                List<String> shows: const <String>[],
                                bool isDeferred: false}) {
    String deferredString = isDeferred ? ' deferred' : '';
    String prefixString = prefix == null ? '' : ' as $prefix';
    String showString = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
    write('import "$uri"$deferredString$prefixString$showString;');
    newline();
  }

  unparseExportTag(String uri, {List<String> shows: const []}) {
    String suffix = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
    write('export "$uri"$suffix;');
    newline();
  }

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

  visitCaseMatch(CaseMatch node) {
    addToken(node.caseKeyword);
    visit(node.expression);
    write(node.colonToken.value);
  }

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

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

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

  visitImport(Import node) {
    addToken(node.importKeyword);
    visit(node.uri);
    if (node.isDeferred) {
      write(' deferred');
    }
    if (node.prefix != null) {
      write(' as ');
      visit(node.prefix);
    }
    if (node.combinators != null) {
      write(' ');
      visit(node.combinators);
    }
    write(node.getEndToken().value);
    newline();
  }

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

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

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

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

  visitMetadata(Metadata node) {
    addToken(node.token);
    visit(node.expression);
  }

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