// Copyright (c) 2020, 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:compiler/src/constants/values.dart' show StringConstantValue;
import 'package:compiler/src/js_backend/string_reference.dart'
    show StringReference, StringReferenceResource, StringReferenceFinalizerImpl;

import 'package:compiler/src/js/js.dart' show prettyPrint;
import 'package:js_ast/js_ast.dart' as js;

void test(List<String> strings, String expected, {bool minified = false}) {
  var finalizer = StringReferenceFinalizerImpl(
    minified,
    shortestSharedLength: 5,
  );

  for (var string in strings) {
    finalizer.addCode(StringReference(StringConstantValue(string)));
  }

  StringReferenceResource resource = StringReferenceResource();
  finalizer.registerStringReferenceResource(resource);
  finalizer.finalize();

  // Wrap the resource in a block, as they would print in actual code.
  Expect.equals(expected.trim(), prettyPrint(js.Block([resource])).trim());
}

extension on List<String> {
  List<String> operator *(int count) {
    return List.filled(count, this).expand((list) => list).toList();
  }
}

void main() {
  // No strings yields an empty pool.
  test([], r'''
{
}''');

  // Single occurrence strings are not pooled.
  test(
    ['Yellow', 'Blue', 'Crimson'],
    r'''
{
}''',
  );

  // Repeated strings that are long enough are pooled.
  test(
    ['Yellow', 'Blue', 'Blue', 'Crimson', 'Crimson'],
    r'''
{
  var string$ = {
    Crimso: "Crimson"
  };
}''',
  );

  // Readable property names have identical stretches compressed-out.
  var greets = [
    'Greetings Bob Smith',
    'Great work!',
    'Greetings Alice',
    'Greetings Bob Henry',
  ];

  test(greets * 2, r'''
{
  var string$ = {
    Great_: "Great work!",
    GreetiA: "Greetings Alice",
    GreetiBH: "Greetings Bob Henry",
    GreetiBS: "Greetings Bob Smith"
  };
}''');

  // Non-identifiers are replaced with '_' if that is unambiguous.
  test(['xylograph', '!pingpong'] * 2, r'''
{
  var string$ = {
    _pingp: "!pingpong",
    xylogr: "xylograph"
  };
}''');

  final strings1 = [
    ...['a xylograph'] * 2,
    ...['a !pingpong'] * 4,
    ...['a %percent'] * 6,
  ];

  // Multiple discriminating non-identifier characters are replaced with an
  // escape, which causes a potentially ambiguous non-escape to be escaped.
  test(strings1, r'''
{
  var string$ = {
    a_x21pin: "a !pingpong",
    a_x25per: "a %percent",
    a_x78ylo: "a xylograph"
  };
}''');

  // Minified version keeps the strings in the same order as unminified, and
  // tries to allocate the same minified name.
  const minified1 = r'''
{
  var string$ = {
    l: "a !pingpong",
    o: "a %percent",
    n: "a xylograph"
  };
}''';

  final strings2 = [
    ...['a xylograph'] * 20, // now most frequent.
    ...strings1,
  ];
  test(strings1, minified1, minified: true);
  test(strings2, minified1, minified: true);
}
