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

// @dart = 2.10

// Note: This test relies on LF line endings in the source file.

// Test that JS printer callbacks occur when expected.

library js_ast.printer.callback_test;

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

enum TestMode {
  INPUT,
  NONE,
  ENTER,
  DELIMITER,
  EXIT,
}

class TestCase {
  final Map<TestMode, String> data;

  /// Map from template names to the inserted values.
  final Map<String, String> environment;

  const TestCase(this.data, [this.environment = const {}]);
}

const List<TestCase> DATA = <TestCase>[
  TestCase({
    TestMode.NONE: '''
function(a, b) {
  return null;
}''',
    TestMode.ENTER: '''
@0function(@1a, @2b) @3{
  @4return @5null;
}''',
    TestMode.DELIMITER: '''
function(a, b) {
  return null@4;
@0}''',
    TestMode.EXIT: '''
function(a@1, b@2) {
  return null@5;
@4}@3@0'''
  }),
  TestCase({
    TestMode.NONE: '''
function() {
  if (true) {
    foo1();
    foo2();
  } else if (false) {
    bar1();
    bar2();
  }
  while (false) {
    baz3();
    baz4();
  }
}''',
    TestMode.ENTER: '''
@0function() @1{
  @2if (@3true) @4{
    @5@6@7foo1();
    @8@9@10foo2();
  } else @11if (@12false) @13{
    @14@15@16bar1();
    @17@18@19bar2();
  }
  @20while (@21false) @22{
    @23@24@25baz3();
    @26@27@28baz4();
  }
}''',
    TestMode.DELIMITER: '''
function() {
  if (true) {
    foo1();
    foo2();
  } else if (false) {
    bar1();
    bar2();
  }
  while (false) {
    baz3();
    baz4();
  }
@0}''',
    TestMode.EXIT: '''
function() {
  if (true@3) {
    foo1@7()@6;
@5    foo2@10()@9;
@8  }@4 else if (false@12) {
    bar1@16()@15;
@14    bar2@19()@18;
@17  }@13
@11@2  while (false@21) {
    baz3@25()@24;
@23    baz4@28()@27;
@26  }@22
@20}@1@0''',
  }),
  TestCase({
    TestMode.NONE: '''
function() {
  function foo() {
  }
}''',
    TestMode.ENTER: '''
@0function() @1{
  @2@3function @4foo() @5{
  }
}''',
    TestMode.DELIMITER: '''
function() {
  function foo() {
  @3}
@0}''',
    TestMode.EXIT: '''
function() {
  function foo@4() {
  }@5@3
@2}@1@0'''
  }),
  TestCase({
    TestMode.INPUT: """
function() {
  a['b'];
  [1,, 2];
}""",
    TestMode.NONE: '''
function() {
  a.b;
  [1,, 2];
}''',
    TestMode.ENTER: '''
@0function() @1{
  @2@3@4a.@5b;
  @6@7[@81,@9, @102];
}''',
    TestMode.DELIMITER: '''
function() {
  a.b;
  [1,, 2];
@0}''',
    TestMode.EXIT: '''
function() {
  a@4.b@5@3;
@2  [1@8,,@9 2@10]@7;
@6}@1@0''',
  }),
  TestCase({
    TestMode.INPUT: 'a.#nameTemplate = #nameTemplate',
    TestMode.NONE: 'a.nameValue = nameValue',
    TestMode.ENTER: '@0@1@2a.@3nameValue = @3nameValue',
    TestMode.DELIMITER: 'a.nameValue = nameValue',
    TestMode.EXIT: 'a@2.nameValue@3@1 = nameValue@3@0',
  }, {
    'nameTemplate': 'nameValue'
  }),
];

class FixedName extends Name {
  @override
  final String name;
  @override
  String get key => name;

  FixedName(this.name);
}

void check(TestCase testCase) {
  Map<TestMode, String> map = testCase.data;
  String code = map[TestMode.INPUT];

  // Input is the same as output.
  code ??= map[TestMode.NONE];

  JavaScriptPrintingOptions options = JavaScriptPrintingOptions();
  Map arguments = {};
  testCase.environment.forEach((String name, String value) {
    arguments[name] = FixedName(value);
  });
  Node node = js.parseForeignJS(code).instantiate(arguments);
  map.forEach((TestMode mode, String expectedOutput) {
    if (mode == TestMode.INPUT) return;
    Context context = Context(mode);
    Printer(options, context).visit(node);
    // TODO(johnniwinther): Remove `replaceAll(...)` when dart2js behaves as the
    // VM on newline in multiline strings.
    expect(context.getText(), equals(expectedOutput.replaceAll('\r\n', '\n')),
        reason: 'Unexpected output for $code in $mode');
  });
}

class Context extends SimpleJavaScriptPrintingContext {
  final TestMode mode;
  final Map<Node, int> idMap = {};
  final Map<int, List<String>> tagMap = {};

  Context(this.mode);

  int id(Node node) => idMap.putIfAbsent(node, () => idMap.length);

  String tag(int value) => '@$value';

  @override
  void enterNode(Node node, int startPosition) {
    int value = id(node);
    if (mode == TestMode.ENTER) {
      tagMap.putIfAbsent(startPosition, () => []).add(tag(value));
    }
  }

  @override
  void exitNode(
      Node node, int startPosition, int endPosition, int delimiterPosition) {
    int value = id(node);
    if (mode == TestMode.DELIMITER && delimiterPosition != null) {
      tagMap.putIfAbsent(delimiterPosition, () => []).add(tag(value));
    } else if (mode == TestMode.EXIT) {
      tagMap.putIfAbsent(endPosition, () => []).add(tag(value));
    }
  }

  @override
  String getText() {
    String text = super.getText();
    int offset = 0;
    StringBuffer sb = StringBuffer();
    for (int position in tagMap.keys.toList()..sort()) {
      if (offset < position) {
        sb.write(text.substring(offset, position));
      }
      tagMap[position].forEach((String tag) => sb.write(tag));
      offset = position;
    }
    if (offset < text.length) {
      sb.write(text.substring(offset));
    }
    return sb.toString();
  }
}

void main() {
  test('printer callback test', () {
    DATA.forEach(check);
  });
}
