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

library dart2js.ir_nodes_sexpr;

import '../constants/values.dart';
import '../util/util.dart';
import 'cps_ir_nodes.dart';
import '../universe/call_structure.dart' show
    CallStructure;

/// A [Decorator] is a function used by [SExpressionStringifier] to augment the
/// output produced for a node or reference.  It can be provided to the
/// constructor.
typedef String Decorator(node, String s);

/// Generate a Lisp-like S-expression representation of an IR node as a string.
class SExpressionStringifier extends Indentation implements Visitor<String> {
  final _Namer namer = new _Namer();

  String newValueName(Primitive node) => namer.nameValue(node);
  String newContinuationName(Continuation node) => namer.nameContinuation(node);
  Decorator decorator;

  SExpressionStringifier([this.decorator]) {
    if (this.decorator == null) {
      this.decorator = (node, String s) => s;
    }
  }

  /// Create a stringifier with an extra layer of decoration.
  SExpressionStringifier withDecorator(Decorator subDecorator) {
    return new SExpressionStringifier((node, String s) {
      return subDecorator(node, decorator(node, s));
    });
  }

  /// Create a stringifier that displays type information.
  SExpressionStringifier withTypes() => withDecorator(typeDecorator);

  /// Creates a stringifier that adds annotations from a map;
  /// see [Node.debugString].
  SExpressionStringifier withAnnotations(Map annotations) {
    return withDecorator(decoratorFromMap(annotations));
  }

  static Decorator decoratorFromMap(Map annotations) {
    Map<Node, String> nodeMap = {};
    for (var key in annotations.keys) {
      if (key is Node) {
        nodeMap[key] = '${annotations[key]}';
      } else {
        String text = key;
        Node node = annotations[key];
        if (nodeMap.containsKey(node)) {
          // In case two annotations belong to the same node,
          // put both annotations on that node.
          nodeMap[node] += ' $text';
        } else {
          nodeMap[node] = text;
        }
      }
    }
    return (node, string) {
      String text = nodeMap[node];
      if (text != null) return '***$string*** $text';
      return string;
    };
  }

  static String typeDecorator(node, String string) {
    return node is Variable ? '$string:${node.type}' : string;
  }

  String access(Reference<Definition> r) {
    if (r == null) return '**** NULL ****';
    return decorator(r, namer.getName(r.definition));
  }

  String optionalAccess(Reference<Definition> reference) {
    return reference == null ? '()' : '(${access(reference)})';
  }

  String visitParameter(Parameter node) {
    return namer.nameParameter(node);
  }

  String visitMutableVariable(MutableVariable node) {
    return namer.nameMutableVariable(node);
  }

  /// Main entry point for creating a [String] from a [Node].  All recursive
  /// calls must go through this method.
  String visit(Node node) {
    if (node == null) return '**** NULL ****';
    String s = node.accept(this);
    return decorator(node, s);
  }

  String formatThisParameter(Parameter thisParameter) {
    return thisParameter == null ? '()' : '(${visit(thisParameter)})';
  }

  String visitFunctionDefinition(FunctionDefinition node) {
    String name = node.element.name;
    String thisParameter = formatThisParameter(node.thisParameter);
    String parameters = node.parameters.map(visit).join(' ');
    namer.setReturnContinuation(node.returnContinuation);
    String body = indentBlock(() => visit(node.body));
    return '$indentation'
        '(FunctionDefinition $name $thisParameter ($parameters) return\n'
        '$body)';
  }

  String visitLetPrim(LetPrim node) {
    String name = newValueName(node.primitive);
    String value = visit(node.primitive);
    String bindings = '($name $value)';
    String skip = ' ' * '(LetPrim ('.length;
    while (node.body is LetPrim) {
      node = node.body;
      name = newValueName(node.primitive);
      value = visit(node.primitive);
      String binding = decorator(node, '($name $value)');
      bindings += '\n${indentation}$skip$binding';
    }
    String body = indentBlock(() => visit(node.body));
    return '$indentation(LetPrim ($bindings)\n$body)';
  }

  bool isBranchTarget(Continuation cont) {
    return cont.hasExactlyOneUse && cont.firstRef.parent is Branch;
  }

  String visitLetCont(LetCont node) {
    String conts;
    bool first = true;
    String skip = ' ' * '(LetCont ('.length;
    for (Continuation continuation in node.continuations) {
      // Branch continuations will be printed at their use site.
      if (isBranchTarget(continuation)) continue;
      if (first) {
        first = false;
        conts = visit(continuation);
      } else {
        // Each subsequent line is indented additional spaces to align it
        // with the previous continuation.
        conts += '\n${indentation}$skip${visit(continuation)}';
      }
    }
    // If there were no continuations printed, just print the body.
    if (first) return visit(node.body);

    String body = indentBlock(() => visit(node.body));
    return '$indentation(LetCont ($conts)\n$body)';
  }

  String visitLetHandler(LetHandler node) {
    // There are no explicit references to the handler, so we leave it
    // anonymous in the printed representation.
    String parameters = node.handler.parameters
        .map((p) => '${decorator(p, newValueName(p))}')
        .join(' ');
    String handlerBody =
        indentBlock(() => indentBlock(() => visit(node.handler.body)));
    String body = indentBlock(() => visit(node.body));
    return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)';
  }

  String visitLetMutable(LetMutable node) {
    String name = visit(node.variable);
    String value = access(node.value);
    String body = indentBlock(() => visit(node.body));
    return '$indentation(LetMutable ($name $value)\n$body)';
  }

  String formatArguments(CallStructure call,
      List<Reference<Primitive>> arguments,
      [CallingConvention callingConvention = CallingConvention.Normal]) {
    int positionalArgumentCount = call.positionalArgumentCount;
    if (callingConvention == CallingConvention.Intercepted ||
        callingConvention == CallingConvention.DummyIntercepted) {
      ++positionalArgumentCount;
    }
    List<String> args =
        arguments.take(positionalArgumentCount).map(access).toList();
    List<String> argumentNames = call.getOrderedNamedArguments();
    for (int i = 0; i < argumentNames.length; ++i) {
      String name = argumentNames[i];
      String arg = access(arguments[positionalArgumentCount + i]);
      args.add("($name: $arg)");
    }
    // Constructors can have type parameter after the named arguments.
    args.addAll(
        arguments.skip(positionalArgumentCount + argumentNames.length)
            .map(access));
    return '(${args.join(' ')})';
  }

  String visitInvokeStatic(InvokeStatic node) {
    String name = node.target.name;
    String args = formatArguments(node.selector.callStructure, node.arguments);
    return '(InvokeStatic $name $args)';
  }

  String visitInvokeMethod(InvokeMethod node) {
    String name = node.selector.name;
    String rcv = access(node.receiver);
    String args = formatArguments(node.selector.callStructure, node.arguments,
        node.callingConvention);
    return '(InvokeMethod $rcv $name $args)';
  }

  String visitInvokeMethodDirectly(InvokeMethodDirectly node) {
    String receiver = access(node.receiver);
    String name = node.selector.name;
    String args = formatArguments(node.selector.callStructure, node.arguments,
        node.callingConvention);
    return '(InvokeMethodDirectly $receiver $name $args)';
  }

  String visitInvokeConstructor(InvokeConstructor node) {
    // TODO(karlklose): for illegal nodes constructed for tests or unresolved
    // constructor calls in the DartBackend, we get an element with no enclosing
    // class.  Clean this up by introducing a name field to the node and
    // removing [ErroneousElement]s from the IR.
    String name = node.dartType != null
        ? node.dartType.toString()
        : node.target.enclosingClass.name;
    if (!node.target.name.isEmpty) {
      name = '${name}.${node.target.name}';
    }
    String args = formatArguments(node.selector.callStructure, node.arguments);
    return '(InvokeConstructor $name $args)';
  }

  String visitInvokeContinuation(InvokeContinuation node) {
    String name = access(node.continuation);
    if (node.isRecursive) name = 'rec $name';
    String args = node.arguments == null
        ? '**** NULL ****'
	: node.arguments.map(access).join(' ');
    String escaping = node.isEscapingTry ? ' escape' : '';
    return '$indentation(InvokeContinuation $name ($args)$escaping)';
  }

  String visitThrow(Throw node) {
    String value = access(node.value);
    return '$indentation(Throw $value)';
  }

  String visitRethrow(Rethrow node) {
    return '$indentation(Rethrow)';
  }

  String visitBranch(Branch node) {
    String condition = access(node.condition);
    assert(isBranchTarget(node.trueContinuation.definition));
    assert(isBranchTarget(node.falseContinuation.definition));
    String trueCont =
        indentBlock(() => visit(node.trueContinuation.definition));
    String falseCont =
        indentBlock(() => visit(node.falseContinuation.definition));
    String strict = node.isStrictCheck ? 'Strict' : 'NonStrict';
    return '$indentation(Branch $strict $condition\n$trueCont\n$falseCont)';
  }

  String visitUnreachable(Unreachable node) {
    return '$indentation(Unreachable)';
  }

  String visitConstant(Constant node) {
    String value = node.value.accept(new ConstantStringifier(), null);
    return '(Constant $value)';
  }

  String visitContinuation(Continuation node) {
    if (isBranchTarget(node)) {
      assert(node.parameters.isEmpty);
      assert(!node.isRecursive);
      return indentBlock(() => visit(node.body));
    }
    String name = newContinuationName(node);
    if (node.isRecursive) name = 'rec $name';
    // TODO(karlklose): this should be changed to `.map(visit).join(' ')`
    // and should recurse to [visit].  Currently we can't do that, because
    // the unstringifier_test produces [LetConts] with dummy arguments on
    // them.
    String parameters = node.parameters
        .map((p) => '${decorator(p, newValueName(p))}')
        .join(' ');
    String body = indentBlock(() => indentBlock(() => visit(node.body)));
    return '($name ($parameters)\n$body)';
  }

  String visitGetMutable(GetMutable node) {
    return '(GetMutable ${access(node.variable)})';
  }

  String visitSetMutable(SetMutable node) {
    String value = access(node.value);
    return '(SetMutable ${access(node.variable)} $value)';
  }

  String visitTypeCast(TypeCast node) {
    String value = access(node.value);
    String typeArguments = node.typeArguments.map(access).join(' ');
    return '(TypeCast $value ${node.dartType} ($typeArguments))';
  }

  String visitTypeTest(TypeTest node) {
    String value = access(node.value);
    String typeArguments = node.typeArguments.map(access).join(' ');
    return '(TypeTest $value ${node.dartType} ($typeArguments))';
  }

  String visitTypeTestViaFlag(TypeTestViaFlag node) {
    String interceptor = access(node.interceptor);
    return '(TypeTestViaFlag $interceptor ${node.dartType})';
  }

  String visitLiteralList(LiteralList node) {
    String values = node.values.map(access).join(' ');
    return '(LiteralList ($values))';
  }

  String visitSetField(SetField node) {
    String object = access(node.object);
    String field = node.field.name;
    String value = access(node.value);
    return '(SetField $object $field $value)';
  }

  String visitGetField(GetField node) {
    String object = access(node.object);
    String field = node.field.name;
    return '(GetField $object $field)';
  }

  String visitGetStatic(GetStatic node) {
    String element = node.element.name;
    return '(GetStatic $element)';
  }

  String visitSetStatic(SetStatic node) {
    String element = node.element.name;
    String value = access(node.value);
    return '(SetStatic $element $value)';
  }

  String visitGetLazyStatic(GetLazyStatic node) {
    String element = node.element.name;
    return '(GetLazyStatic $element)';
  }

  String visitCreateBox(CreateBox node) {
    return '(CreateBox)';
  }

  String visitCreateInstance(CreateInstance node) {
    String className = node.classElement.name;
    String arguments = node.arguments.map(access).join(' ');
    String typeInformation = optionalAccess(node.typeInformation);
    return '(CreateInstance $className ($arguments) ($typeInformation))';
  }

  String visitInterceptor(Interceptor node) {
    return '(Interceptor ${access(node.input)})';
  }

  String visitReifyRuntimeType(ReifyRuntimeType node) {
    return '(ReifyRuntimeType ${access(node.value)})';
  }

  String visitReadTypeVariable(ReadTypeVariable node) {
    return '(ReadTypeVariable ${access(node.target)}.${node.variable})';
  }

  String visitTypeExpression(TypeExpression node) {
    String args = node.arguments.map(access).join(' ');
    return '(TypeExpression ${node.kindAsString} ${node.dartType} ($args))';
  }

  String visitCreateInvocationMirror(CreateInvocationMirror node) {
    String selector = node.selector.name;
    String args = node.arguments.map(access).join(' ');
    return '(CreateInvocationMirror $selector ($args))';
  }

  String visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
    String operator = node.operator.toString();
    String args = node.arguments.map(access).join(' ');
    return '(ApplyBuiltinOperator $operator ($args))';
  }

  String visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
    String method = node.method.toString();
    String receiver = access(node.receiver);
    String args = node.arguments.map(access).join(' ');
    return '(ApplyBuiltinMethod $method $receiver ($args))';
  }

  String visitForeignCode(ForeignCode node) {
    String arguments = node.arguments.map(access).join(' ');
    return '(JS "${node.codeTemplate.source}" ($arguments))';
  }

  String visitGetLength(GetLength node) {
    String object = access(node.object);
    return '(GetLength $object)';
  }

  String visitGetIndex(GetIndex node) {
    String object = access(node.object);
    String index = access(node.index);
    return '(GetIndex $object $index)';
  }

  String visitSetIndex(SetIndex node) {
    String object = access(node.object);
    String index = access(node.index);
    String value = access(node.value);
    return '(SetIndex $object $index $value)';
  }

  @override
  String visitAwait(Await node) {
    String value = access(node.input);
    return '(Await $value)';
  }

  @override
  String visitYield(Yield node) {
    String value = access(node.input);
    return '(Yield $value)';
  }

  String visitRefinement(Refinement node) {
    String value = access(node.value);
    return '(Refinement $value ${node.type})';
  }

  String visitBoundsCheck(BoundsCheck node) {
    String object = access(node.object);
    String index = optionalAccess(node.index);
    String length = optionalAccess(node.length);
    return '(BoundsCheck $object $index $length ${node.checkString})';
  }

  String visitReceiverCheck(ReceiverCheck node) {
    String value = access(node.value);
    String condition = optionalAccess(node.condition);
    return '(ReceiverCheck $value ${node.selector} $condition '
        '${node.flagString}))';
  }
}

class ConstantStringifier extends ConstantValueVisitor<String, Null> {
  // Some of these methods are unimplemented because we haven't had a need
  // to print such constants.  When printing is implemented, the corresponding
  // parsing support should be added to SExpressionUnstringifier.parseConstant
  // in the dart2js tests (currently in the file
  // tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart).

  String _failWith(ConstantValue constant) {
    throw 'Stringification not supported for ${constant.toStructuredString()}';
  }

  String visitFunction(FunctionConstantValue constant, _) {
    return '(Function "${constant.unparse()}")';
  }

  String visitNull(NullConstantValue constant, _) {
    return '(Null)';
  }

  String visitInt(IntConstantValue constant, _) {
    return '(Int ${constant.unparse()})';
  }

  String visitDouble(DoubleConstantValue constant, _) {
    return '(Double ${constant.unparse()})';
  }

  String visitBool(BoolConstantValue constant, _) {
    return '(Bool ${constant.unparse()})';
  }

  String visitString(StringConstantValue constant, _) {
    return '(String ${constant.unparse()})';
  }

  String visitList(ListConstantValue constant, _) {
    String entries =
      constant.entries.map((entry) => entry.accept(this, _)).join(' ');
    return '(List $entries)';
  }

  String visitMap(MapConstantValue constant, _) {
    List<String> elements = <String>[];
    for (int i = 0; i < constant.keys.length; ++i) {
      ConstantValue key = constant.keys[i];
      ConstantValue value = constant.values[i];
      elements.add('(${key.accept(this, _)} . ${value.accept(this, _)})');
    }
    return '(Map (${elements.join(' ')}))';
  }

  String visitConstructed(ConstructedConstantValue constant, _) {
    return '(Constructed "${constant.unparse()}")';
  }

  String visitType(TypeConstantValue constant, _) {
    return '(Type "${constant.representedType}")';
  }

  String visitInterceptor(InterceptorConstantValue constant, _) {
    return '(Interceptor "${constant.unparse()}")';
  }

  String visitSynthetic(SyntheticConstantValue constant, _) {
    return '(Synthetic "${constant.unparse()}")';
  }

  String visitDeferred(DeferredConstantValue constant, _) {
    return _failWith(constant);
  }
}

class _Namer {
  final Map<Node, String> _names = <Node, String>{};
  int _valueCounter = 0;
  int _continuationCounter = 0;

  // TODO(sra): Make the methods not assert and print something indicating an
  // error, so printer can be used to inspect broken terms.

  String nameParameter(Parameter parameter) {
    assert(!_names.containsKey(parameter));
    String name =
        parameter.hint != null ? parameter.hint.name : nameValue(parameter);
    return _names[parameter] = name;
  }

  String nameMutableVariable(MutableVariable variable) {
    assert(!_names.containsKey(variable));
    return _names[variable] = variable.hint.name;
  }

  String nameContinuation(Continuation node) {
    assert(!_names.containsKey(node));
    return _names[node] = 'k${_continuationCounter++}';
  }

  String nameValue(Primitive node) {
    assert(!_names.containsKey(node));
    return _names[node] = 'v${_valueCounter++}';
  }

  void setReturnContinuation(Continuation node) {
    assert(!_names.containsKey(node) || _names[node] == 'return');
    _names[node] = 'return';
  }

  String getName(Node node) {
    if (!_names.containsKey(node)) return 'MISSING_NAME';
    return _names[node];
  }
}
