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

import 'package:expect/expect.dart';
import 'package:js_ast/js_ast.dart';

main() {
  Map<Expression, DeferredExpression> map = {};
  VariableUse variableUse = new VariableUse('variable');
  DeferredExpression deferred =
      map[variableUse] = new _DeferredExpression(variableUse);
  VariableUse variableUseAlias = new VariableUse('variable');
  map[variableUseAlias] = new _DeferredExpression(variableUseAlias);

  map[deferred] = new _DeferredExpression(deferred);
  Literal literal = new LiteralString('"literal"');
  map[literal] = new _DeferredExpression(literal);

  test(map, '#', [variableUse], 'variable');
  test(map, '#', [deferred], 'variable');
  test(map, '{#: #}', [literal, variableUse], '{literal: variable}');
  test(map, '{#: #}', [literal, deferred], '{literal: variable}');
  test(map, '#.#', [variableUse, literal], 'variable.literal');
  test(map, '#.#', [deferred, literal], 'variable.literal');
  test(map, '# = # + 1', [variableUse, variableUseAlias], '++variable');
  test(map, '# = # + 1', [deferred, variableUseAlias], '++variable');
  test(map, '# = # - 1', [variableUse, variableUseAlias], '--variable');
  test(map, '# = # - 1', [deferred, variableUseAlias], '--variable');
  test(map, '# = # + 2', [variableUse, variableUseAlias], 'variable += 2');
  test(map, '# = # + 2', [deferred, variableUseAlias], 'variable += 2');
}

void test(Map<Expression, DeferredExpression> map, String template,
    List<Expression> arguments, String expectedOutput) {
  Expression directExpression =
      js.expressionTemplateFor(template).instantiate(arguments);
  _Context directContext = new _Context();
  Printer directPrinter =
      new Printer(const JavaScriptPrintingOptions(), directContext);
  directPrinter.visit(directExpression);
  Expect.equals(expectedOutput, directContext.text);

  Expression deferredExpression = js
      .expressionTemplateFor(template)
      .instantiate(arguments.map((e) => map[e]).toList());
  _Context deferredContext = new _Context();
  Printer deferredPrinter =
      new Printer(const JavaScriptPrintingOptions(), deferredContext);
  deferredPrinter.visit(deferredExpression);
  Expect.equals(expectedOutput, deferredContext.text);

  for (Expression argument in arguments) {
    DeferredExpression deferred = map[argument];
    Expect.isTrue(
        directContext.enterPositions.containsKey(argument),
        "Argument ${DebugPrint(argument)} not found in direct enter positions: "
        "${directContext.enterPositions.keys}");
    Expect.isTrue(
        deferredContext.enterPositions.containsKey(argument),
        "Argument ${DebugPrint(argument)} not found in "
        "deferred enter positions: "
        "${deferredContext.enterPositions.keys}");
    Expect.isTrue(
        deferredContext.enterPositions.containsKey(deferred),
        "Argument ${DebugPrint(deferred)} not found in "
        "deferred enter positions: "
        "${deferredContext.enterPositions.keys}");
    Expect.equals(directContext.enterPositions[argument],
        deferredContext.enterPositions[argument]);
    Expect.equals(directContext.enterPositions[argument],
        deferredContext.enterPositions[deferred]);

    Expect.isTrue(
        directContext.exitPositions.containsKey(argument),
        "Argument ${DebugPrint(argument)} not found in direct enter positions: "
        "${directContext.exitPositions.keys}");
    Expect.isTrue(
        deferredContext.exitPositions.containsKey(argument),
        "Argument ${DebugPrint(argument)} not found in "
        "deferred enter positions: "
        "${deferredContext.exitPositions.keys}");
    Expect.isTrue(
        deferredContext.exitPositions.containsKey(deferred),
        "Argument ${DebugPrint(deferred)} not found in "
        "deferred enter positions: "
        "${deferredContext.exitPositions.keys}");
    Expect.equals(directContext.exitPositions[argument],
        deferredContext.exitPositions[argument]);
    Expect.equals(directContext.exitPositions[argument],
        deferredContext.exitPositions[deferred]);
  }
}

class _DeferredExpression extends DeferredExpression {
  final Expression value;

  _DeferredExpression(this.value);

  @override
  int get precedenceLevel => value.precedenceLevel;
}

class _Context implements JavaScriptPrintingContext {
  StringBuffer sb = new StringBuffer();
  List<String> errors = [];
  Map<Node, int> enterPositions = {};
  Map<Node, _Position> exitPositions = {};

  @override
  void emit(String string) {
    sb.write(string);
  }

  @override
  void enterNode(Node node, int startPosition) {
    enterPositions[node] = startPosition;
  }

  @override
  void exitNode(
      Node node, int startPosition, int endPosition, int closingPosition) {
    exitPositions[node] =
        new _Position(startPosition, endPosition, closingPosition);
    Expect.equals(enterPositions[node], startPosition);
  }

  @override
  void error(String message) {
    errors.add(message);
  }

  String get text => sb.toString();
}

class _Position {
  final int startPosition;
  final int endPosition;
  final int closingPosition;

  _Position(this.startPosition, this.endPosition, this.closingPosition);

  int get hashCode =>
      13 * startPosition.hashCode +
      17 * endPosition.hashCode +
      19 * closingPosition.hashCode;

  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is _Position &&
        startPosition == other.startPosition &&
        endPosition == other.endPosition &&
        closingPosition == other.closingPosition;
  }

  String toString() {
    return '_Position(start=$startPosition,'
        'end=$endPosition,closing=$closingPosition)';
  }
}
